How to create a mock REST API with ApiGateway
How to create by AWS CLI
Having to mock and api for a integration test can be easily solved when you are working with microservices, since you are already building something with Flask or Express, create a mock is just a matter of setup new endpoints and put your stub there.
But, in this case, I was working with a system based on Lambda and deploy a API in this case would take too much resources in AWS, so I saw this alternative with ApiGateway.
As the name self-explain, it’s a resource on AWS that you can define your API and scale, redirect and so on.
Let’s look how to create one and put some mock. First, create it:
Create Api
$ aws apigateway create-rest-api --name test-mock
{
"id": "API_ID",
"name": "test-mock",
"createdDate": 00000,
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
}
}
Next step is to create the endpoint, which is called Resource. First we get the id of the root resource:
$ aws apigateway get-resources --rest-api-id API_ID
{
"items": [
{
"id": "ROOT_RESOURCE_ID",
"path": "/"
}
]
}
Now creating our resource
Create Resource
$ aws apigateway create-resource --rest-api-id API_ID --parent-id ROOT_RESOURCE_ID --path-part hello
{
"id": "ENDPOINT_ID",
"parentId": "ROOT_RESOURCE_ID",
"pathPart": "hello",
"path": "/hello"
}
Set for which method this resource will answer (I’m using GET for this example): Also, this will be public, without authentication
Create Method
$ aws apigateway put-method --rest-api-id API_ID --resource-id ENDPOINT_ID --http-method GET --authorization-type NONE
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false
}
Set this method to work as a mock:
Create Integration
$ aws apigateway put-integration --rest-api-id API_ID --resource-id ENDPOINT_ID --http-method GET --type MOCK --request-templates '{ "application/json": "{\"statusCode\": 200}" }'
{
"type": "MOCK",
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "ENDPOINT_ID",
"cacheKeyParameters": []
}
We need to set a method response, in this case, will create for status code 200
$ aws apigateway put-method-response --rest-api-id=5uqyz3qfj5 --resource-id 1ej64s --http-method GET --status-code 200 --response-models application/json=Empty
{
"statusCode": "200"
}
Finally, the stub itself:
Create Stub
$ aws apigateway put-integration-response --rest-api-id API_ID --resource-id ENDPOINT_ID --http-method GET --status-code 200 --response-templates '{"application/json": "{\"Hello\": \"World\"}"}'
{
"statusCode": "200",
"responseTemplates": {
"application/json": "{\"Hello\": \"World\"}"
}
}
Deploy your API:
Deploy API
$ aws apigateway create-deployment --rest-api-id API_ID --stage-name STAGE_NAME
{
"id": "DEPLOYMENT_ID",
"createdDate": 00000000
}
After this, your deployment will be available in the following link:
https://{API_ID}.execute-api.eu-west-1.amazonaws.com/STAGE_NAME
As we created the resource /hello, you will reach it at:
https://{API_ID}.execute-api.eu-west-1.amazonaws.com/STAGE_NAME/hello
Export to JSON file
It’s also possible to export a create API and only import it. Let’s export the API above:
Export API
$ aws apigateway get-export --rest-api-id API_ID --stage-name stage --export-type oas30 --parameters extensions='integrations' api_definition.json
{
"contentType": "application/octet-stream",
"contentDisposition": "attachment; filename=\"oas30_2020-10-09T13:47:37Z.json\""
}
Generate API importing
If you have the API file definitions and want to import it, just:
Import API
$ aws apigateway import-rest-api --body 'file:///path/to/API_Swagger_template.json'
{
"id": "NEW_ID",
"name": "test-mock",
"createdDate": 00000000,
"version": "0000-00-00T13:47:37Z",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
}
}
And deploy it, as show in Deploy API