Configuración de APIs diseñadas en RAML con Amazon API Gateway

Publicado por Luis Miguel Fernández Teomiro el

CloudAmazon API GatewayRAMLAmazon AWS

En este post vamos a ver cómo definir una API sencilla  RAML en ATOM con el paquete API Workbench, cómo crear un mock de este API utilizando Osprey Mock Service y cómo importar este API en Amazon API Gateway.

Introducción

El conocido concepto de API está evolucionando en la actualidad gracias a la demanda de apertura de los Sistemas de Información para cubrir un escenario multicanal. Las tendencias de movilidad, Cloud e IoT impulsan esta transformación digital y sitúan a las APIs como activos empresariales de gran valor.

El éxito de la estrategia API se basa en dos pilares fundamentales, que son:

  • Un enfoque basado en diseñar primero el API en texto plano y bajo un lenguaje legible por humanos, permitiendo la documentación de la misma y la creación de mocks por parte de proveedores y consumidores.
  • La administración del API bajo una plataforma de gestión y ejecución que aporte las funcionalidades comunes al ecosistema de APIs corporativo, como son la seguridad, la calidad del servicio o las estadísticas.

Entorno

Osprey necesita que Git esté presente en la máquina y se instala mediante el gestor de paquetes de JavaScript npm incluido en Node.js:

npm install -g osprey-mock-service

API Workbench se instala mediante el gestor de paquetes APM de ATOM:

apm install api-workbench

AWS API Gateway Importer necesita que AWS Command Line Interface (CLI) esté instalado y configurado previamente:

...\aws-apigateway-importer-master>aws configure
AWS Access Key ID [****************3S6A]: ****************3S6A  
AWS Secret Access Key [****************XHn+]:****************XHn+  
Default region name [eu-ireland]: eu-west-1  
Default output format [json]: json  

AWS API Gateway Importer ha de ser ensamblado mediante Maven:

...\aws-apigateway-importer-master>mvn assembly:assembly

Definición del API

Creamos un nuevo proyecto RAML en API Workbench:

ProyectoRAML

No marcamos el uso de la versión 1.0 porque AWS API Gateway Importer y Osprey solo trabajan actualmente con la versión 0.8 de RAML.

Por otro lado, indicamos que se cree la estructura de directorio por defecto y seleccionamos la opción para crear un recurso y un método de ejemplo, que será todo el contenido de la sencilla definición de API con la que vamos a trabajar.

#%RAML 0.8
title: HelloWorldAPI  
version: v1  
baseUri: http://api.samplehost.com  
/helloWorld:
  get:
    responses:
      200:
        body:
          application/json:
            example: |
              {
                "message" : "Hello World"
              }
APIRAML

Si lanzamos una prueba desde la consola HelloWorldAPI de API Workbench contra la dirección por defecto, configurada en el parámetro baseUri, obtenemos un error ya que no hay ninguna implementación del API escuchando en http://api.samplehost.com.

Creación del Mock del API

Para poder probar el API y enviar peticiones desde API Workbench vamos a arrancar un servicio mock de Osprey en el puerto 8000 de nuestra máquina local. A este servicio le indicamos el archivo RAML de definición de nuestro API:

osprey-mock-service -f api.raml -p 8000

...\newRamlProject>osprey-mock-service -f api.raml -p 8000
Mock service running at http://localhost:8000  

Si volvemos a lanzar la petición anterior, desde API Workbench, obtenemos una respuesta con el código 200 de OK basada en el ejemplo que hemos definido en el API RAML.

{ "message" : "Hello World" }

Respuesta200

En el mock service podemos observar el log de la petición recibida:

::ffff:127.0.0.1 - - [20/May/2016:10:53:57 +0000] "GET /helloWorld HTTP/1.1" 200 - "-" "API Workbench: Console"

Importación del API

El siguiente paso que vamos a realizar va a ser la importación del API en Amazon API Gateway, para ello vamos a utilizar la herramienta proporcionada para tal fin por el fabricante.

Para la correcta importación se ha de tener en cuenta que el valor del campo baseUri en el API ha de terminar con el carácter slash (/) y que el comando se debe de ejecutar desde el directorio donde se encuentre ubicada la definición del API. En caso de no cumplirse estas condiciones obtendremos un excepción de tipo StringIndexOutOfBoundsException para el primer caso o una excepción de tipo NullPointerException para el segundo caso.

C:\Users\lmfernandez\newRamlProject>C:\Programas\aws-apigateway-importer-master\aws-api-import.cmd -c api.raml --region eu-west-1

C:\Users\lmfernandez\newRamlProject>java -jar C:\Programas\aws-apigateway-importer-master\target/aws-apigateway-importer-1.0.3-SNAPSHOT-jar-with-dependencies.jar  -c api.  
raml --region eu-west-1  
2016-05-20 11:04:34,965 INFO - Using API Gateway endpoint https://apigateway.eu-west-1.amazonaws.com  
2016-05-20 11:04:36,660 INFO - Attempting to create API from RAML definition. RAML file: api.raml  
2016-05-20 11:04:36,771 INFO - Creating API with name HelloWorldAPI  
2016-05-20 11:04:37,044 INFO - Created API h42q4avzr6  
2016-05-20 11:04:37,222 INFO - Removing default model Error  
2016-05-20 11:04:37,305 INFO - Removing default model Empty  
2016-05-20 11:04:37,506 INFO - Creating resource 'helloWorld' on vbadqpknm5  
2016-05-20 11:04:37,667 INFO - Creating method for api id h42q4avzr6 and resource id 3o2p32 with method GET  

Una vez realizada la importación podemos observar en la consola del Gateway la existencia de la nueva API denominada HelloWorldAPI.

APIEnGateway

Si entramos en el detalle del recurso /helloWorld podemos observar como la configuración del método GET todavía no está creada:

DetalleAPI

Configuración del API en el Gateway

En este punto debemos indicar el endpoint del servicio, la función Lambda o el AWS Service Proxy que se atacaría desde el Gateway. En nuestro caso vamos a simular la integración creando una respuesta que indique que la petición se ha procesado correctamente en el Gateway.

Clickamos en Set up now y seleccionamos Mock Integration

APIMock

En este momento nos aparecen cuatro actividades: Method Request, Integration Request Integration Response y Method Response.

GETDetalle

En la actividad Integration Response del método GET indicamos la respuesta mock que vamos a devolver cuando lleguen peticiones.

{ "message" : "Hello World from Amazon API Gateway!" }

GETMapping
GETResponse

Como hemos visto en la pantalla de detalle del API, desde el propio API Gateway se puede lanzar un test para comprobar el funcionamiento de la lógica que hemos implementado en el método.

GETTestResuesta

Podemos observar que el comportamiento es el esperado:

Request: /helloWorld  
Status: 200  
Latency: 0 ms  
Response Body  
{
  "message": "Hello World from Amazon API Gateway!"
}
Response Headers  
{"Content-Type":"application/json"}
Logs  
Execution log for request test-request  
Fri May 20 09:23:52 UTC 2016 : Starting execution for request: test-invoke-request  
Fri May 20 09:23:52 UTC 2016 : HTTP Method: GET, Resource Path: /helloWorld  
Fri May 20 09:23:52 UTC 2016 : Method request path: {}  
Fri May 20 09:23:52 UTC 2016 : Method request query string: {}  
Fri May 20 09:23:52 UTC 2016 : Method request headers: {}  
Fri May 20 09:23:52 UTC 2016 : Method request body before transformations: null  
Fri May 20 09:23:52 UTC 2016 : Endpoint response body before transformations:  
Fri May 20 09:23:52 UTC 2016 : Endpoint response headers: {}  
Fri May 20 09:23:52 UTC 2016 : Method response body after transformations: {  
  "message" : "Hello World from Amazon API Gateway!"
}
Fri May 20 09:23:52 UTC 2016 : Method response headers: {Content-Type=application/json}  
Fri May 20 09:23:52 UTC 2016 : Successfully completed execution  
Fri May 20 09:23:52 UTC 2016 : Method completed with status: 200  

Ahora es el momento de desplegar nuestra API en un entorno (stage) del API Gateway para hacerla accesible desde el exterior. Como en este caso no tenemos ningun stage creado procedemos a crearlo:

StageCreacion

Marcamos la opción Enable CloudWatch Metrics para que se exporten las estadísticas al producto CloudWatch de AWS y obtenemos el endpoint en el cual hemos publicado el API:

Invoke URL: https://h42q4avzr6.execute-api.eu-west-1.amazonaws.com/dev

ConfiguracionMetricas

Invocando al API desde el exterior

Para comprobar el funcionamiento del API desplegado vamos a cambiar el endpoint al que atacábamos en Atom para indicar el que hemos obtenido mediante la consola. Procedemos a realizar la invocación y vemos que recibimos la respuesta que definimos en el Gateway:

InvocacionDesdeAtom

{ "message" : "Hello World from Amazon API Gateway!" }

Para poder ver los dashboards de CloudWatch con cierta información vamos a lanzar varias veces la petición durante unos minutos desde Atom y entonces podremos observar en dicho cuadro la cantidad de peticiones lanzadas y la latencia de las mismas:

APIMetricas

A partir de este momento ya podríamos empezar a utilizar todas las funcionalidades que nos ofrece Amazon API Gateway sobre nuestro API RAML y que no hemos configurado en este post.

Échale un vistazo a otros posts sobre Amazon AWS para más información. ¡Y síguenos en Twitter!