A common use case of API Gateway is building API endpoints in top of Lambda functions. It can also be used as an API proxy to connect to AWS services. In this guide, I will walk you through how to create your own API using API Gateway and DynamoDB only and go through advanced features to enhance your API endpoints such as: Mapping templates, Integration Request and Integration Response. Error handling and request validation. Authentication with AWS Cognito and Lambda Authorizer. API Throttling with Plan usage and API keys. API documentation generation. API Gateway custom domain. Setting up DynamoDB To get started, create a DynamoDB table called with an as a partition key (leave the read/write capacity to default values): movies id Next, insert few items into the table, it should look something like this: Next, we need to grant the API Gateway access to DynamoDB table. Therefore we need to create an IAM role assumable by API Gateway: The role will give API Gateway permission to invoke the following DynamoDB operations on table: movies API Endpoints Before going into further detail about the architecture, the following diagram shows how API Gateway and DynamoDB will fit into the API architecture: Serverless API Architecture When calling the API endpoints, the request will go through the API Gateway, which will invoke the appropriate DynamoDB operation. This returns a response which is proxied by the API Gateway to the client in a JSON format. GET /movies Create new API called from , and create a new resource, let’s call it : MoviesAPI API Gateway Console movies Expose a method on resource by clicking on “ ”. Select under the “ ” section, choose the service, set the HTTP method to be and action type to be a operation. GET /movies Create Method AWS Service Integration type DynamoDB POST Scan Next, we need to transform the HTTP request coming into API Gateway to a proper request for DynamoDB. In the API Gateway console, select the “ ”. All the way at the bottom we can select the Body Mapping Templates. Here, create a new mapping template with the following configuration: Scan Integration Request application/json Deploy the API from “ ” and create a new deployment stage, an invocation URL will be displayed: Actions Point your browser to the URL given or use a modern REST client like Postman. The endpoint will return a list of movies in a JSON format: The output is returned in DynamoDB response format, in order to map the raw response to traditional JSON object structure, we will use feature. Integration Response Click on “ ” method and navigate to “ ”, expand the 200 response code. Expand the “ s” section. In choose and create a mapping template that loop through each item from the array, extracts the relevant attributes of the movie’s item and places them into a response structure: GET Integration Response Mapping Template Content-Type application/json Items is a script expressed in and applied to the payload using . Mapping template Velocity Template Language (VTL) JSONPath expressions As a result, you should now see a formatted response. GET /movies/:id The second endpoint will be responsible of fetching a movie based on an ID provided by the client. Hence, a new resource with a path parameter should be created. The value of ID will be made available via the method: $input.params(‘id’) Expose a GET method, and then link the resource to the DynamoDB service. The action will be operation: GetItem Again, specify a body mapping template for the integration request, now with the following template: When the API URL is invoked with an ID, the movie corresponding to the ID is returned if it exists. Similarly we will use integration response to map the raw DynamoDB response to the similar JSON object structure we defined earlier: If you test it out once again, the following JSON will be returned: POST /movies Now we know how the method works with and without path parameters. The next step will be to insert a new item to the table. Create a method with as an action: GET POST PutItem We will create a mapping template to transform the client request into the structure that the DynamoDB API requires. The below mapping template creates the JSON structure required by the DynamoDB PutItem API. The three input variables are referenced from the request JSON using the variable: PutItem $input Back in the “ ” pane click “ ”. Create an example request body that matches the API definition documented above and then choose “ ”. For example, your request body could be: Method Execution TEST Test Navigate to the DynamoDB console and view the table to show that the request really was successfully processed: movies Try to insert a new movie without giving a movie’s name attribute. The following error will returned: It’s a DynamoDB PutItem error. Fortuently, API Gateway allows you to validate your request body before invoking the downstream resources (In our example the DynamoDB table). To achieve this, we will use API Gateway Models. A Model defines the payload data structure. Models definitions are written using JSON Schema draft 4. In the API Gateway, navigate to the Models tab and create a new model. Fill in the form as so: The model above defines a entity with 3 attributes and requires and attributes to be defined (used during validation). movie id name Head back to “ ” page and click on “ ” from the method, enable the request validator option as below: Resources Method Request POST If you try to insert a new movie without providing the required parameters, a bad request message error will be returned: You can override the default 400 message from the “ ” as follows: Gateway Responses As a result, the user defined error message will be returned: Great! Try implementing the and methods: PUT DELETE Authentication The serverless API that we have built so far works like a charms. However, its open to the public, anyone can insert data into DynamoDB table if he/she has the API Gateway invocation URL. Luckily, API Gateway offers two ways to handle authentication: API Gateway Authentication with Cognito and Lambda Authorizer Amazon Cognito Create a new user pool, click on “ ” to create a pool with default settings. A success message should be displayed at the end of the creation process: Review defaults After creating your first user pool, register your serverless API from “ under “ and select “ . Give the application a name and check the server-based authentication option: App clients” General settings” Add an app client” ADMIN_NO_SRP_AUTH Create a new user using the AWS command line: Now that the user pool has been created, we can configure the API Gateway to validate access tokens from a successful user pool authentication before granting access to DynamoDB. To begin securing API access, go to API Gateway console, choose the RESTful API that we built in the previously, and click on “ from the navigation bar. Click on the “ button and select “ . Then, select the user pool that we created earlier and set the token source field to . This defines the name of the incoming request header containing the API caller's identity token for Authorization: Authorizers” Create New Authorizer” Cognito” Authorization You can now secure all of the endpoints, for instance, in order to secure the endpoint responsible for creating an new movie. Click on the corresponding method under the resource. Click on the “ box, then on “ , and select the user pool we created previously: POST /movies Method Request” Authorization” Once done, redeploy the API and try to insert a new movie using the API invocation URL. This time, the endpoint is secured and requires authentication: In order to authenticate, we need to obtain an identity token for the signed-in user from the the user pool and include the identity token in the header for the API Gateway requests. Issue the following AWS CLI command to get a new token: Authorization The command above takes a JSON file with the following attributes: Once executed, the preceding command will return the following JSON response: Copy the ID token and add it to the header of your request: Authorization The API Gateway will verify the token and will invoke the operation on the table, which will insert a new movie into the table: PutItem movies Lambda Authorizer When a client sends a request to your API, it will go through the API Gateway, which will extracts the token from the request and calls your Lambda function authorizer with it. The function evaluates the token, generates a policy and sends it back to API Gateway. API Gateway evaluates the policy and invoke the DynamoDB action registered for the API endpoint. For the sake of simplicity, our function will verify if the token provided by the client equals to our secret (environment variable) and returns a policy document based on the result. The following is the function handler source code written in Node.JS: Head back to API Gateway and created a new “ ” and set to be the header API Gateway will extract the token from: Lambda Authorizer Authorization Choose the method you want to secure, let’s say, it will be the endpoint responsible of deleting a movie from the table. Click on “ ” and under select your new authorizer: Method Request Authorization Let’s try calling the endpoint, As expected, we’re not getting through to our real endpoint: If you include the secret token to the header of your request, you should be able to delete an item: Authorization Looks good! API Throttling You can use usage plans combined with API keys to set method-level throttling limits for your API and define how much and how fast clients can access your API (request rates and quotas). The following procedure describes how to create a usage plan: API Usage Create a usage plan called , with a of 1 request per second and of 10000 requests per day: basic throttling limit quota limit Create a 2nd usage plan called , with a of 10 requests per second and a of 1 million requests per day: premium throlling limit quota limit API Keys Next, create two API keys: Assign the first API key to basic usage plan and second key to premium usage plan: Associate the usage plans we created to the API deployment stage: Configure an API method to require an API key: Deploy or redeploy the API for the requirement to take effect: Now if you added the header. If all goes well you will receive output like this: x-api-key If you exceed the rate limit or quota limit associated with your API key, a “ ” HTTP error will be returned: Too many requests Custom Domains You can use your own domain name for an API and deployment stage, create a backed by an (Amazon Certificate Manager) certificate: Custom Domain Name ACM Create a new custom domain name from API Gateway Console: Add a path mapping to map your domain name to your API deployment stage: Once configured, you can query your API using your custom domain name as follows: https://api.serverlessmovies.com/movies Documentation Before finishing this guide, we will go through how to create documentation for the serverless API we’ve built so far. On the API Gateway console, select the deployment stage that you’re interested in generating documentation for. In the following example, I chose the environment. Then, click on the tab and click on the section: sandbox Export Export as Swagger is an implementation of the , which is a standard defined by the Linux Foundation on how to describe and define APIs. This definition is called the . Swagger OpenAPI OpenAPI specification document You can save the document in either a JSON or YAML file. Then, navigate to and paste the content on the website editor, it will be compiled and an HTML page will be generated as follows: https://editor. swagger. io/ Like what you’re reading? Check out my book and learn how to build, secure, deploy and manage production-ready Serverless applications in Golang with AWS Lambda. _Learn to build, secure, deploy, and manage your serverless application in Golang with AWS Lambda_www.packtpub.com Hands-On Serverless Applications with Go | PACKT Books