Amazon Web Services introduced Modelo de aplicación sin servidor, or SAM, a couple of months ago. It defines simplified syntax for expressing
serverless resources. SAM extends AWS CloudFormation to add support for API Gateway, AWS Lambda and Amazon DynamoDB. This blog will show how to create a simple microservice using
SAM. Of course, we’ll use Couchbase instead of DynamoDB! This blog will also use the basic concepts explained in Microservice using AWS API Gateway, AWS Lambda and Couchbase. SAM
will show the ease with which the entire stack for microservice can be deployed and managed.
As a refresher, here are key components in the architecture:
- Client could be curl, AWS CLI/Console, Postman client or any other tool/API that can invoke a REST endpoint.
- AWS API Gateway is used to provision APIs. The top level resource is available at path
/libros
. HTTPGET
yPOST
para el recurso. - Cada API activa una función Lambda. Se crean dos funciones Lambda,
lista de libros
para listar todos los libros disponibles ylibro-crear
para crear un nuevo libro. - Couchbase se utiliza como almacén de persistencia en EC2. Todos los documentos JSON se almacenan y recuperan de esta base de datos.
Other blogs on serverless:
- Microservicios con AWS API Gateway, AWS Lambda y Couchbase
- Botón AWS IoT, Lambda y Couchbase
- Serverless FaaS with Lambda and Java
Empecemos.
Serverless Application Model (SAM) Template
An AWS CloudFormation template with serverless resources conforming to the AWS SAM model is referred to as a SAM file or template. It is deployed
as a CloudFormation stack. Let’s take a look at our SAM template: This template is available at github.com/arun-gupta/serverless/blob/master/aws/microservice/template.yml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
AWSTemplateFormatVersion : '2010-09-09' Transformar: AWS::Serverless-2016-10-31 Descripción: Microservice using API Gateway, Lambda y Couchbase Recursos: MicroserviceGetAllGateway: Tipo: AWS::Serverless::Function Propiedades: Manipulador: org.sample.serverless.aws.couchbase.gateway.BucketGetAll Tiempo de ejecución: java8 CódigoUri: s3://serverless-microservice/microservice-http-endpoint-1.0-SNAPSHOT.jar Tiempo de espera: 30 TamañoMemoria: 1024 Medio ambiente: Variables: COUCHBASE_HOST: ec2-35-163-21-104.us-west-2.compute.amazonaws.com Papel: arn:aws:iam::598307997273:role/microserviceRole Eventos: GetResource: Tipo: Api Propiedades: Ruta: /books Método: get MicroservicePostGateway: Tipo: AWS::Serverless::Function Propiedades: Manipulador: org.sample.serverless.aws.couchbase.gateway.BucketPost Tiempo de ejecución: java8 CódigoUri: s3://serverless-microservice/microservice-http-endpoint-1.0-SNAPSHOT.jar Tiempo de espera: 30 TamañoMemoria: 1024 Medio ambiente: Variables: COUCHBASE_HOST: ec2-35-163-21-104.us-west-2.compute.amazonaws.com Papel: arn:aws:iam::598307997273:role/microserviceRole Eventos: GetResource: Tipo: Api Propiedades: Ruta: /books Método: post |
SAM template Specification provide complete details about contents in the template. The key parts of the template are:
- Defines two resources, both of Lambda Function type identified by
AWS::Serverless::Function
attribute. Name of the Lambda function is defined byResources.
. - Class for each handler is defined by the value of
Resources..Properties.Handler
atributo - Java 8 runtime is used to run the Function defined by
Resources..Properties.Runtime
atributo - Code for the class is uploaded to an S3 bucket, in our case to
s3://serverless-microservice/microservice-http-endpoint-1.0-SNAPSHOT.jar
Resources..Properties.Environment.Variables.COUCHBASE_HOST
attribute value defines the host where Couchbase is running. This can be easily deployed on EC2 as explained at Setup Couchbase.- Each Lambda function is triggered by an API. It is deployed using AWS API Gateway. The path is defined by
Events.GetResource.Properties.Path
. HTTP method is defined usingEvents.GetResource.Properties.Method
atributo.
Java Application
The Java application that contains the Lambda functions is at github.com/arun-gupta/serverless/tree/master/aws/microservice/microservice-http-endpoint.
Lambda function that is triggered by HTTP GET
method is shown:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
público clase BucketGetAll implementa RequestHandler<GatewayRequest, GatewayResponse> { @Anular público GatewayResponse handleRequest(GatewayRequest solicitar, Contexto contexto) { pruebe { N1qlQuery consulta = N1qlQuery .simple(seleccione("*") .de(i(CouchbaseUtil.getBucketName())) .límite(10)); Cadena resultado = CouchbaseUtil.getBucket().consulta(consulta).allRows().toString(); devolver nuevo GatewayResponse(200, resultado, GatewayResponse.HEADERS_JSON); } captura (ConfigurationException e) { devolver nuevo GatewayResponse(400, e.getMessage(), GatewayResponse.HEADERS_TEXT); } } } |
A little bit of explanation:
- Each Lambda function needs to implement the interface
com.amazonaws.services.lambda.runtime.RequestHandler
. - API Gateway and Lambda integration require a specific input format y output format.
These formats are defined asGatewayRequest
yGatewayResponse
clases. - Function logic uses SDK Java de Couchbase to query the Couchbase database. N1QL query is used to query
the database. The results and exception are then wrapped inGatewayRequest
yGatewayResponse
.
Lambda function triggered by HTTP POST method is pretty straightforward as well:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
público clase BucketPost implementa RequestHandler<GatewayRequest, GatewayResponse> { @Anular público GatewayResponse handleRequest(GatewayRequest solicitar, Contexto contexto) { pruebe { JsonDocument documento = CouchbaseUtil.getBucket().upsert(Reserve.fromStringToJson(solicitar.getBody())); devolver nuevo GatewayResponse(200, documento.contenido().toString(), GatewayResponse.HEADERS_JSON); } captura (Excepción ex) { devolver nuevo GatewayResponse(400, ex.getMessage(), GatewayResponse.HEADERS_TEXT); } } } |
A bit of explanation:
- Incoming request payload is retrieved from
GatewayRequest
- Document inserted in Couchbase is returned as response.
- Like the previous method, Function logic uses SDK Java de Couchbase to query the Couchbase database. The results and exception are then
wrapped inGatewayRequest
yGatewayResponse
.
Build the Java application as:
1 |
mvn -f microservicio-http-punto final/pom.xml limpiar paquete |
Upload Lambda Function to S3
SAM template reads the code from an S3 bucket. Let’s create a S3 bucket:
1 |
aws s3 mb s3://serverless-microservice --region us-west-2 |
us-oeste-2
region is one of the supported regions for API Gateway. S3 bucket names are globally unique but their location is region specific. Upload
the code to S3 bucket:
1 |
aws s3 cp microservicio-http-punto final/objetivo/microservicio-http-punto final-1.0-SNAPSHOT.tarro s3://serverless-microservice/microservice-http-endpoint-1.0-SNAPSHOT.jar |
The code is now uploaded to S3 bucket. SAM template is ready to be deployed!
Deploy SAM Template
Deploy the SAM template:
1 2 3 4 |
aws cloudformation despliegue --plantilla-archivo plantilla.yml --pila-nombre microservicio-pasarela --región us-oeste-2 |
Muestra la salida:
1 2 3 |
En espera para changeset a sea creado.. En espera para pila crear/actualización a completa Con éxito creado/actualizado pila - microservicio-pasarela |
This one command deploys Lambda functions and REST Resource/APIs that trigger these Lambda functions.
Invoke the Microservice
API Gateway publishes a REST API that can be invoked by curl, wget, AWS CLI/Console, Postman or any other app that can call a REST API. This blog will use AWS Console to show the interaction. API Gateway home at us-west-2.console.aws.amazon.com/apigateway/home?region=us-west-2#/apis shows:
Click on the API to see all the APIs in this resource:
Click on POST to see the default page for POST method execution:
Click on Test to test the API:
Add the payload in Request Body and click on Prueba
to invoke the API. The results are shown as below:
Now click on GET to see the default execution page:
Click on Test to test the API:
No request body is needed, just click on Test the invoke the API. The results are as shown:
Output from the Couchbase database is shown in the Response Body.