Clojure in AWS Serverless: API Gateway

You’re back! That’s great. It’s time to continue our journey deep into AWS. If somebody offers you red or blue pills, just keep walking.

In the last tutorial we hooked up our Prime generator to Dynamo as a bit of a computational cache. But how can we expose our Prime service to the outside world? Lambda’s are private, so we need something to pass events to our Lambda function.

If only there was a service that handled routing, authentication, payload transformation, and could invoke services like Lambda…

As always, the code is in Github.

But first, incidental setup

Before we get started, make sure you have your DynamoDB table up and running from the last tutorial. If you destroyed it after completing the tutorial, follow the steps under DynamoDB in production and IAM Dynamo permissions for Lambda. You will need access to IAM.

Go ahead and give her a test to make sure everything is working properly.

It’s a bird! It’s a plane! No! It’s API Gateway!

Probably the most misunderstood service in all of AWS, the API Gateway has a staggering depth of functionality. By necessity, we will only cover some of the basics. As we continue in the future I will highlight more of the API Gateway.

First up, we must set up our API Gateway.

  1. In the AWS console page, open the API Gateway dashboard.
  2. Click Create API. If you haven’t created an API before, you will be greeted with a “sample API” from AWS. Skip this by selecting “New API” from the radio boxes.
  3. Give your API a name and description.

Aaaaand you’re done! But wait, something’s missing…

Oh yeah! Our routes! We kinda need those. After creating your API, you will automatically go to that API’s Resources dashboard. This is where you will create and manage your routes.

Methods and Resources

There are two key words you need to remember. If you’re pretty grounded in building APIs this will all sound familiar.

  • Method — GET, POST, and the other HTTP Methods. These translate the method calls to Resources into events aimed at your AWS based services. Inside the AWS API Gateway console, they function as the control board for the other advanced Gateway functionality.
  • Resource — This is the URI used by your application and HTTP Methods. These can be programmed with dynamic values that are used as part of your payload body. Inside the AWS API Gateway console, Resources organize the HTTP methods in a tree structure for easy reference.

Prime Resource

Let’s create a Resource in our API for our prime function.

  • In your API’s Resources group, select Create Resource in the Actions pulldown menu.
  • Set the Resource Name to “Prime”. You will notice it also sets the route that matches the Name as a URL-encoded string. This is a suggestion, and you can change it to something else if you like.
  • Click Create Resource

Now we have our first Resource for primes. But it doesn’t do anything yet. We need to assign some Methods.

Prime Methods

If we are doing proper HTTP like good little programmers, we would use a PUT. We are asking for a calculation and storing the results. It’s also idempotent because the calculation recycles instead of overrides the pre-generated results. Of course we could use any of the HTTP functions (we’re positively mad and drunk with power), so more like guidelines…

  • Select the “Prime” Resource you just created.
  • In the Actions dropdown, click Create Method.
  • A little pulldown will appear with all the HTTP methods. Select PUT.
  • Click the little checkbox.
  • Make sure the Integration Type is Lambda Function
  • Select the region our Lambda is in. For me it’s US-WEST-2
  • Type the name of your Lambda here. There’s autocomplete if you can’t remember. I named mine “Sieve-Lambda”.
  • Click Save
  • A modal dialog will appear asking to give Lambda permissions for the API Gateway. This allows the Gateway to invoke the Lambda with a payload. Click OK.

You are now in the Twili…er the Method Integration panel. Here is where most of the magic happens. Here you control permissions to invoke the Method, how the request payload is transformed, schema check the incoming data, transform the request/response payloads, mapping integration responses to HTTP Status codes and responses…

I mean I could go on…

Rather than dunk you in the river Lethe with a long winding exploration of everything, we will build on this piece-by-piece. For now we will ignore most of this functionality and deploy.

Deploy your API

  • In the API’s Resources group, select Deploy API from the Actions pulldown.
  • In the modal, select [New Stage] from the Deployment pulldown. We will make a staging deployment for our use.
  • Set the Stage Name to “staging”
  • Click Deploy

After a moment, you will automagically go to the Stages group of your API. Here it lists the different deployment configurations you’ve created. These can’t change once deployed. You have to redeploy your API with the desired changes.

The Stages allow you to version and roll back changes in your API. This is important because, as hinted above, there is lots of API boundry functionality in the Gateway. This frees our little service to concentrate on the core bits of logic that matter.

You will also notice a big blue box with Invoke URL promanently advertising for your attention. That is a public endpoint to your API. Now you can open your favorite API testing app and fire off a JSON payload!

If you’ve followed along with the names, you should be able to PUT this payload onto /prime route:

"max": 5

And get…

Monster Trukkin’ Lambdas!
OMG did we just build a Service?! — Everybody

You bet yer bottom dollar!

Of course, if you deviate even a little from the payload, like "max":"5" or "whiskey":"bravo"

Look, our little service is a special snowflake, but under the purging flames of the Internet the poor thing would wither. There’s clearly lots of work to do. Luckily much of this work can be handled through the Gateway itself. In the next tutorial we’ll cover more of this ground.

Make sure you delete any resources (DynamoDB) to keep your costs down!

Some key takeways

  • The API Gateway handles more of the API boundry work instead of our app. We’ll dig into this more in the future. We’ve only scratched the surface.
  • We can create our Resources and Methods and tie them to Lambdas
  • We can Deploy to a Stage to get a public endpoint.
  • We tested our Lambda and API with a tool.

Next we’ll expand our API to handle more methods to our service. As always, you can catch me on Twitter @jamesleonis