My thoughts about AWS API Gateway working with AWS Lambda

Screenshot of AWS API GatewayWell it's been a little while since AWS released their API Gateway. I've been playing around with it in two modes: one for real work and the other for play work (more on that later, when it is time for the big reveal). I decided I should probably collect together some of my thoughts so far about Amazon's API Management service, also known as API Gateway.

Lambda and API Gateway work quite well as complementary services, although there are quite a number of issues that I have discovered and will discuss below.

Most of the feedback below is from a bit of a build of a bit of a secret project at the moment which tries out something slightly radical:

You could build a "server-less" application without running any EC2 or RDS instances

What does this really mean? A bunch of DynamoDB tables, Lambda functions performing basic CRUD on said tables, exposed as a REST API using API Gateway with a bit of S3 to test integration with different AWS services. The great thing is the whole thing is driven based on usage. No usage? Really quiet month? Equals cheap month. And it's not like as things get popular, the costs scale at alarming rates. AWS is already really cheap.

Onwards!

Things that work really quite well

  • Passing things like HTTP headers, path variables (defined with lovely curly braces) or the old school query strings all works well with mapping templates, although I've only really tried pretty basic ones as I don't want to embed too much logic in the API management layer
  • API keys can be added to prevent unauthorised access (message is "Not able to access resource") but the keys are pretty basic
  • Automated acceptance or integration testing is possible once the APIs and Lambda functions are deployed, which works fine for me in my application but won't cut the mustard in an enterprise with a bajillion developers
  • The API Gateway can be deployed via the AWS API, but it looks pretty complicated (CloudFormation isn't supported yet) and I haven't really tried the API yet. I guess I don't have enough methods and resources to warrant it, yet.
  • Lambda can be deployed via the AWS API (or Boto3)
  • Everything goes through HTTPS, which I like a lot. It is convenient without having to set up a web-server and add a key chain etc. It's also a mandatory requirement so you can't get away with plain HTTP, which is a limitation that I like
  • Custom domain names are supported to make it look clean, although a wildcard SSL cert is probably a good idea, so that's what I did for my new project so I can use the same cert for the website, API and any other subdomain
  • You can mix API calls so some are proxied from Lambda and others are proxied from other APIs within the one deployment, but I don't really have a need to proxy anything that isn't Lambda right now
  • API endpoints that are associated with Lambda functions are displayed in Lambda, so you can tell what's happening from the Lambda side of things, which is a nice touch
  • CloudFront is automatically configured with API Gateway, although caching is basically on or off (so there isn't much control over config, refer to the API)
  • Caching is pay-by-the-hour for each stage that has been deployed and only takes a few minutes to get going
  • Logging to Cloudtrail is effective and easy to find specific errors or stack traces provided you put the odd console log message here and there in your code

Things that could be improved

This list is longer than the good stuff, but really it's early days and I can see there is great scope for future product releases.

  • At the moment, language choices are either Java or Node.js. I would rather some other language choices, like Python or Go, but I guess Node.js will have to do for the moment
  • Passing errors back from Lambda to map to HTTP status codes doesn't really work for JSON payloads, also there is not much documentation on this function
  • The list of Lambda functions cannot be structured in any way, so it's just a "big list of functions"
  • I would really like to see the Sydney region being activated. Please! Latency to Oregon is not good
  • Automated unit testing isn't really possible because you can't run a local instance of API Gateway. So maybe you can test Lambda. Maybe. But the API Gateway config is a little out of reach of current unit testing tools.
  • Local dev environments are not possible for API Gateway nor is a local mock. Would be nice to have something similar to the mock DynamoDB environment
  • Lambda allows you to delete a Lambda function even when a API Gateway method still refers to the function, which is a bit dodgy
  • It seems difficult to partition version of lambda functions or for multiple people to work using a region at a time in the same account, which is fine for me because there is just me, but it's going to be really annoying for teams that share AWS accounts
  • Overall, configuring the API Gateway is more manual than it could be when using the GUI as you can't cascade things like "Needs API Key" (so you have to enable API Keys for each and every method) - see point below
  • The "Configure Sample Event" in Lambda doesn't allow you to save your own sample events (also seems to lose the current sample event when logging out of the console)
  • You can't define any method at the very top (or root) of the domain, (it would be nice to put some sort of information page here) eg:
  • You can do some sort of versioning of the API Gateway but there is no versioning of Lambda. And you are most likely going to need versioning in Lambda because that's where you will want to make all of your little tweaks and changes
  • It's not really clear what properties you can get from the "event" and "context" objects in Lambda
  • Doesn't seem possible to pass the user's IP address or other typical HTTP request headers back to Lambda via API Gateway
  • Requesting API Gateway stages that aren't there returns "message: null" payload
  • Requesting API Gateway paths that aren't there returns "message: Missing Authentication Token" payload, which is a bit weird
  • Disabling CloudTrail logging in API Gateway still means that Lambda logs executions of the functions in CloudTrail... this is a little confusing for me anyway
  • Setting up CORS is straightforward but tedious (when referring to the documentation). What this means is you need to set up an OPTIONS method for every URL path (resource in API Gateway terminology) but also a header value for every API method. Ouch.
  • Some configuration is only available in the API, not in the front end. For example: defining the TTL for the API cache or enabling encryption of the cache. I'm not really sure if the GUI enables encryption by default as I haven't tried out the API yet.
  • The minimum cache size is 0.5GB, but I can't tell if the selected size is appropriate or if you are running out of cache or any form of analysis on what the setting should be. So should I pick the minimum cos it costs the least?
  • One of my biggest concers is the API Gateway lacks a cascading configuration model with the ability to override at individual nodes for the following:
    • Enabling API Keys
    • CORS (also automatically configuring CORS headers for available method names, with an override)
    • Header variables
    • Authorisation Type (eg IAM)
    • Mapping templates for errors (often you want the same error code, eg 404 for 'not found', for lots of different resources)

CORS

CORS is annoying at the best of times. To setup CORS in AWS API Gateway (refer to this doc, step #5) rather than following the guide 100%, point the OPTIONS method to a dummy Node.js Lambda function that does nothing, for example:

exports.handler = function(event, context) { context.succeed(); };

UPDATE: This no longer seems to be required because there is a new option called "Mock Integration". See this link for more info.

So there you have it. That's almost all the things I have experienced so far with Amazon's API Gateway. There's probably a few more points here and there but I really wanted to focus on the combination of AWS Lambda and AWS Gateway as they are really complementary products. That's complementary as in work well together, not complimentary freebies when you arrive in a restaurant.