Build a Serverless API in Seconds with Go

The future of rapid application development

Tom Maiaroto
Serif & Semaphore
Published in
6 min readDec 18, 2016

--

There’s a landscape change on the internet every six years or so. One is happening right now. Maybe you’ve heard buzzwords such as “serverless” or “microservices” or “NoOps.”

During the course of my research, I built a few open-source projects. One of these I nicknamed Aegis. What this project has allowed me to do is build a scalable RESTful API with Go (golang) in an extremely rapid fashion.

Then the`up` command deployed a scalable API in seconds.

While building Aegis, I didn’t want to re-invent any wheels per se. I have used several tools for serverless hosting providers and have enjoyed them all. I have great respect for them and their maintainers. Their goals are for speed and scalability as well. I believe this is the future of rapid application development.

Though some of these frameworks and tools set out to accomplish many goals for many users. They support multiple languages, service providers, and are feature rich. Here’s a complete list of serverless resources for Go.

I was looking for a simpler solution.

I have worked on open-source frameworks before and have used many others. I enjoy their internals and comparing them to understand the different approaches they take. I like to understand the benefits and tradeoffs. I don’t believe in the word best in this regard.

I’m a firm believer in keeping frameworks lean yet modular and open. Sometimes this means being a little opinionated when it allows for a common problem to be solved really well. It’s a delicate balance.

When I was comparing Azure Functions with AWS Lambda I noticed something extremely convenient about Azure. That was that it provided you with a URL to call your function. It supported any HTTP method. It was essentially an effortless mini API. A hook or trigger is fair, but in it I saw a glimmer of something with a lot more potential.

API Gateway previously required each HTTP method to be configured if you wanted them all.

Now, at that time AWS API Gateway was a bit of a painstaking process to get setup to work the same. I think someone was listening though. Since then, Amazon has added an ANY HTTP method to API Gateway resources which handles any method (POST, GET, PUT, etc.). They also have a Lambda Proxy which can be used with a proxy path to handle any URL path with any number of querystring parameters.

You can now simplify your API Gateway configuration. This can handle the same requests as the one above.

The configuration is less involved now, but still not as simple as Azure’s. Regardless, it functionally provides what I was after. Yet, none of the other tools take advantage of it (yet).

I started Aegis under an opinionated pretense as an experiment. It uses AWS Lambda and API Gateway with Go. The scope is small, but it has room to grow. I’m not sure I want to call it a framework, today, but it’s beginning to really define a paradigm. A very familiar one if you’re used to writing APIs.

Hey, this looks rather familiar...

Along with being a little opinionated, Aegis also was able to simplify things. That was by design.

It takes just one command to deploy your highly scalable API.

I was further motivated to build this tool by TJ Holowaychuk’s article (the author of Apex). Though I also understand why he is not making API Gateway more a part of Apex for now (including noted concerns about API Gateway’s speed).

There’s certainly more features that I’d like to add to Aegis. This is only the beginning, but already it’s proving to be a valuable time saver for me.

So what exactly do you get from Aegis?
What’s the point?

  • Single command deploys/updates for your API
  • A single AWS Lambda to handle each API
    (this is a fairly big differentiator, more on this below)
  • A “router” that will allow you to write your API in a more familiar way
  • Route handlers
  • Middleware
  • POST form-data support
  • A variety of helpers for working with incoming event data
  • Environment variable support
  • API response cache support
  • Simple YAML based configuration for your API and Lambda settings
  • Automatic logging to CloudWatch (Go’s log functions will go straight to CloudWatch and there’s also Logrus included with Aegis so you can easily add adapters to log anywhere)
Aegis has a helper function that will parse multipart form data.

Aegis was written in Go and can be installed as a binary.

If you’re starting from scratch, in a clean directory, you’ll likely want to run aegis init to create a little starter app and configuration.

Then simply by running aegis up the program will use your configured AWS credentials (typically in a simple ~/.aws/credentials file) and deploy from the current working directory to Amazon. It will show you the API endpoint URL in your terminal. You need not even log into AWS web console. That’s it, you’re done. Enjoy your API.

It’s very fast to deploy or update and it uses Amazon’s API under the hood. It does not involve CloudFormation or lead you to using a tool like Terraform.

A Note About an Architecture Decision

Many serverless frameworks aim to follow a stricter practice of microservices or cloud functions where each function is small. Actually, not small — tiny.

With Aegis, I decided to make it bigger. By that I mean I wanted each Lambda (or microservice) to comprise of an entire component or concern. So a “blog” would be its own API and perhaps its comment system another Lambda with its own API.

The beauty of a service oriented architecture is that you can really choose how you define those services and break up concerns.

Your application architecture should not just be for server resource management, but also for people management. Teams can more easily work in parallel when you think in terms of (micro)services. That’s part of why Uber can support so many engineers for example.

The only exception here is if the limitations of the cloud function service are such that they support only a few concurrent runs of the same function, while different functions don’t count toward that limit.

In that case, you can better avoid service limits by having multiple functions. Fortunately, the concurrent limit with AWS Lambda is per region — not function. Though with Azure functions, the concurrent limit is per function (used to be 4, then 10, but now varies based on resources). So with Azure, you might want to have your functions smaller and more spread out. With AWS, I’m not so sure you need things that spread out.

In fact, critics of microservices maintain that having too many tiny functions creates a burden on maintenance and debugging. The choice is yours to make though.

The Future?

Serverless is a hot topic. I think with new hosting services, tools and technology, we’ve only seen the beginning. I already see more and more companies adopting it into their stacks.

Of course Docker is already a very big deal and companies like Uber are really championing in microservices. I feel that serverless is merely a companion to this story. It helps form this new landscape.

Will Aegis support providers other than AWS? Unlikely. If I were to use another provider, it would be under a whole new project.

Will Aegis support more than Go? I’m not sure just yet. You never know where my research may lead. I think building a simple serverless RESTful API in Swift would be awesome for iOS developers (and yes, you can run Swift in AWS Lambda with a wrapper too). So I might look into that next.

One thing is for certain — it will remain simple.

Give it a try and feel free to leave feedback or even contribute. It’s still under active development and there’s more to come. While I never intended on building a framework or tool to put out there, I do believe in open-source so most of my research and projects simply end up becoming open-source. Take from it what you will. Maybe the tool can help you too.

--

--