Your second serverless multi-tier web app on AWS

Jeshan Babooa
LambdaTV
Published in
12 min readOct 22, 2017

Introduction

This tutorial resumes where the first part in this series stopped.

To recap, I showed you how to get your first multi-tier architecture set up on AWS:

  • How to host your frontend code on S3
  • How to set up your first API with API Gateway
  • How to create your first serverless function with AWS Lambda
  • And how to set up your first DynamoDB table

I also showed how to use your own domain, how to script the process from start to finish.

All that while kissing server management goodbye :)

In this video, I want to cover what you’re likely going to want to do after doing all that.

Topics

  • Designing an API with Swagger
  • Walkthrough of API and Lambda functions
  • Integrating a custom SDK into your app
  • Creating another lambda function and configuring it
  • Using a CDN to make the frontend faster
  • Using a free SSL certificate

Swagger as an API management tool

What is Swagger?

Swagger is a very popular open source framework for working with APIs.

It allows you to design your API using a web editor in language agnostic manner.

Why bother with Swagger?

You can generate documentation and even use it to generate boilerplate code for many frameworks on your behalf. It can generate client and server code for Node.JS, Spring MVC, C# and many others. It can even output a JMeter script, which is an open source tool that you can consider for your load testing needs.

Why bother with Swagger when working with API Gateway?

API Gateway supports integration for Swagger. That means we can import and export Swagger configuration in and out of API Gateway whether automatically with the SDKs or manually with the admin console. And frankly, it’s more fun to work with Swagger than the API Gateway admin console.

Last but not least, a reason to use Swagger is in case you want to have the option of hosting your API elsewhere. At any time you can generate a Swagger definition even if you never used Swagger in the API before.

Walkthrough

What the demo is about

In this demo, we’ll continue with the TodoMVC example that I started. But in this second part, I’m going to show you how to write the API from the ground up using Swagger. I’ll also cover how to use a Amazon’s CloudFront CDN to make the site load faster and I’ll talk about scripts to automate this process.

The lambda function and the DynamoDB table will remain the same as the one before, i.e the multi-tier function and the todo table:

Designing the API

There are some differences compared with how I showed you when writing the API from API Gateway. For example, API Gateway allows you to write an “ANY” HTTP method. This is just a convenience in API Gateway that matches requests of “any” HTTP method. In Swagger, you’ll have to define a resource and method for each.

The Swagger editor

The Swagger project includes a web-based editor that you can use to author APIs. You can get it from GitHub or you can use the hosted version available at

http://editor.swagger.io

You define your API using YAML in the left pane and on the right you get a live nicely formatted output:

After you define your endpoints, you can even test your API right from the browser:

As you can see, you can generate boilerplate code for many languages:

There are many examples available for you to get started. View them in File > Open Example:

This is not a full tutorial on the Swagger spec, so let me give you the basics so that you can follow along.

You write some basic information in the info section:

You should also specify things like basePath, consumes and produces to define how your API interacts with clients.

Your paths to your API methods and resources go under “path”. For each path, you can define your HTTP methods, tell it what parameters it accepts, what response to send back to the browser, etc.

Tip:

I suggest you always enclose the strings in between quotes otherwise, the Swagger editor may not recognise some values like URLs or even separate words as strings.

You will notice some $ref properties. For example, there’s the response

This means that we will return an array of items that are of type “todo” with the HTTP 200 code. “todo” is a custom object. Swagger allows you to define your own models under the definitions section. The following is how we could define a todo with 3 attributes:

Specifying the format can come in handy especially when working with statically typed languages like Java. For example, in the generated SDK for a Java client, an integer type of int64 will be translated to the Java Long class, instead of the regular Integer class:

Swagger with API Gateway

Let’s now import this API into API Gateway onto our existing multi-tier api:

https://console.aws.amazon.com/apigateway

You can paste what you wrote in the Swagger editor here. But you can also import a Swagger file:

API Gateway doesn’t fully support the Swagger spec so you may run into warnings like the following:

When API Gateway shows me errors like this, I click ignore just like any good developer would ignore compiler warnings 😃

After that, API Gateway will have overwritten your API with the new definition:

You can now start defining which endpoints to use our Lambda function. Repeat the same steps for each HTTP method shown below:

You’ll notice that API Gateway has imported the additional data you specified in the Swagger definition file:

The documentation in Swagger is also imported:

Notice the little blue and orange buttons:

These are hints to guide you through API Gateway. Feel free to explore them.

The lambda function

Our function could remain almost the same but we’ll have to make some modifications to API Gateway calls to make it work. Recall that our function reads input from the event object as follows:

API Gateway doesn’t know that the event object should be of this structure. In the first part, we could get away with it because the “ANY” HTTP method automatically created the object structure for us. For now, we are not using the ANY method. So, we’ll have to tell API Gateway how to construct the event object each time.

We do that by editing the integration request of the method:

For GET on the / base resource, we specify a body mapping template with the following body:

{ "httpMethod": "GET", "headers": null }

We put headers null because we didn’t handle the possibility of headers being undefined in the first part of the tutorial (we didn’t have to). But feel free to do so now 😉

We repeat the same process for the other 3 methods.

For POST on /

For GET on /{id}:

For DELETE on /{id}:

We now deploy our changes so that it’s ready to be used outside the AWS admin console:

Make the site faster using CloudFront, Amazon’s CDN

CloudFront can deliver your static site and digital media to a global network of servers to help you deliver a better experience for your users.

To do that, we create a distribution to tell CloudFront from where to pull our site, configure caching, amongst many other things.

Go to https://console.aws.amazon.com/cloudfront

Create a distribution:

Click Get Started under Web delivery method:

Enter the Origin Domain Name exactly in this format, not the one suggested in the dropdown:

BUCKET_NAME.s3-website-BUCKET_REGION.amazonaws.com

For example, I would input: multitier.jeshan.co.s3-website-eu-west-1.amazonaws.com

Choose Yes for Compress Objects Automatically.

Leave all the other settings to their default values and create the distribution:

This process will take about 10 minutes to deploy your frontend code to Amazon’s global CDN. So wait for the status to turn to Deployed:

When it’s complete, your website will now be available at a domain like: https://d2f10lp5lucyco.cloudfront.net/

Nice domain, huh? You can now tell your users to find your app here :)

“You’re not seriously telling me to give my users such a domain to type… are you?”

No! To fix that, let’s go back to the Cloudfront distribution you created: to use the domain you chose before

Put the domain that you picked before as an Alternate Domain Name:

Then save it:

Also, you’ll likely want your user to always use HTTPS. Let’s configure CloudFront to enforce that for us. You do that by modifying the existing behaviour that you got when you created the distribution:

Change the Viewer Protocol Policy to “Redirect HTTP to HTTPS”:

Then submit the form to save it.

Now, you need to update the DNS record that you created earlier. For example, I chose multitier.jeshan.co . So, I change my CNAME record from:

to the CloudFront url for the distribution:

At this point, we’re still using CloudFront’s SSL certificate. Since we want the users to type our own domain, we need a SSL certificate on our own domain. You can get one for free with AWS itself through its service called AWS Certificate Manager (ACM). You can get there via your CloudFront distribution. Back to where you just edited the Distribution Settings:

Select a Custom SSL certificate and click the Request or Import a Certificate with ACM button:

You will be sent to the Certificate Manager screen. Enter a domain, then click Review and Request. Please ensure that you’re requesting the certificate in us-east-1 (N. Virginia) as currently it’s a requirement to be able to use the certificate on CloudFront. On the next screen, click Confirm and Request:

You should get an email like the following. Follow the instructions:

Approve the certificate request:

By the way, you can view the status of your certificate on the ACM console:

https://console.aws.amazon.com/acm/home?region=us-east-1#/

Now we need to tell CloudFront to use this certificate. Go back to where we were before and click the refresh button and pick the newly created certificate:

Click Yes, Edit to confirm the changes. As usual, the changes take an eternity 10–15 minutes to take effect in CloudFront.

When that’s done and the DNS record change has propagated, your website will be available. Type your domain without the http and see that your browser redirects you to https and shows you a nice green lock…

with a certificate on our name :)

“Is my site really faster now?”

Yes, you can check the difference with the Google PageSpeed insights tool:

Here’s the results without the CDN:

Here’s how the site scores when using the CDN:

A jump from 36 to 70 (on desktop only) is pretty neat. That’s just by leveraging the CDN. And even despite us not bothering minifying the app and using proper cache headers which is beyond the scope of this channel. If you do that, you can easily score over 90 on both mobile and desktop.

Scripts to automate the process

Except a few cases where manual intervention is a must, like approving a SSL certificate, the process can be fully run via scripts.

There are 3 scripts in all. The reason I’ve them split is to make it clear that you need to provide a certain input for one to be able to run them.

  • 3-request-certificate.sh
  • 4-setup-custom-domain-and-ssl.sh
  • 5-check-cloudfront-status.sh

In future tutorials, I’ll make the scripts easier to work with, I’ll be using Python to write deployment scripts as it’s more approachable for most people and we can leverage the boto3 sdk to make it easier to work with AWS APIs.

Recap

Benefits of this architecture (besides AWS’s reliable infrastructure):

  • Frontend that loads very fast for a global audience
  • Frontend delivered securely over https… with a free SSL certificate on your own domain
  • Your backend that’s also “infinitely” scalable.
  • Both logic and data tiers are also secured on the backend.
  • Your website is always serving customers with no server maintenance bullshit whatsoever…

Original article: https://www.lambdatv.com/Your-second-serverless-multi-tier-web-app-on-AWS-part-2

--

--

Jeshan Babooa
LambdaTV

Serverless Guy. Loves AWS Lambda. Intellij fan(atic).