/ :: blog

Writing a personal whois API

Making use of Golang, Lambda, and API Gateway

A while back I wrote a whois API to contain some basic information about me. It was written in Node.JS, and had different JSON responses based on the path you requested (e.g. /name, /job, etc.). The code is here if you are interested in how the first iteration of this project worked. It was hosted on an intentionally-unnamed SaaS provider that just wasn't up to scratch.

Every two weeks at $dayjob, we get the day to work on our own projects, with the expectation to learn and develop yourself and your skills. This time, I decided that I would rewrite my whois API as a Lambda function written in Go, and put it behind AWS’ API Gateway product.

I knew this time round that I wanted to just return a load of JSON on /, rather than split it up into different paths. I started writing it out as an anonymous struct but that started to become unwieldy quite quickly:

json.Marshal(struct {
        Name  string
        ContactDetails struct {
            Mobile string
            Landline string
        }
    }{Name: "Oliver Leaver-Smith", ContactDetails: struct {
        Mobile string
        Landline string
    }{Mobile: "+447450217558", Landline: "+41143601337"}}

I quickly realised that this was going to get ridiculous as the JSON response became more complex, so I turned to my trust Golang resource Tomy for assistance. He reminded me that it would be better to make a type and then set the fields of a new instance of this type, which would be a lot cleaner. A snippet of this looks as follows:

type jsonPayload struct {
    PersonalDetails struct {
        Name struct {
            Fullname struct {
                Canonical string
                Preferred string
            }
        }
    }
}

values := jsonPayload{}

values.PersonalDetails.Name.Fullname.Canonical = "Oliver John Leaver-Smith"
values.PersonalDetails.Name.Fullname.Preferred = "Oliver Leaver-Smith"

I have used serverless a few times in the past for little Lambda projects, so thought I would go the same route this time too. Serverless will automatically create your Lambda and everything required to run it, including the API gateway. It also has some handy docs about how to use the Golang AWS Lambda handlers in your application.

The API Gateway endpoint that you are provided by Serverless is a bog-standard AWS one with a URL as long as your arm. I wanted to shorten it. Thankfully, I had already delegated DNS authority of a subdomain api.ols.wtf to Route53, and so I could easily use that custom domain for the API Gateway endpoint. I went with /whois, and removed the requirement to send an API key as a header, and there it was—available to the world.

$ curl -s https://api.ols.wtf/whois | jq -r .About
This is a simple application to display my "whois". It includes all the details you should need in order to get in touch with me, and also to decide if you actually want to. It is as Lambda function hosted in AWS, behind their API Gateway product, available the domain https://api.ols.wtf/whois (but as you're here, you probably already knew that). The code is hosted here: https://git.sr.ht/~ols/whois

The new code is available here, my next job is to get some automation around deployments of the API, but that is probably for another day.