Serverless API Mocks

Marcin Sodkiewicz
7 min readFeb 25, 2023

--

Recently I found a great product for mocking APIs — Mockoon. It’s not only easy to use, well-designed, versatile and beautiful. It can also be deployed in multiple ways and can support your complicated test case scenarios.

Intro / TL;DR

Mockoon can be used to define mocked APIs using dynamic response templates, simulated failures, delays and it supports scenarios. It has really good integration with Open API and it’s really easy to deploy as it can be easily dockerised, run locally as a service and even supports serverless!

Open API & Swagger Support

You can very easily convert Open API specification with Mockoon to API Mock. It’s really nice as it automatically generates dynamic templates from OpenAPI.

Let’s see it in action:

  1. Download & install Mockoon with installer for platform you’re using
  2. Download Open API Specificiation that can be found on github
  3. Import that file into Mockoon

4. It will create full collection that can be started using play button

5. We can consume our API using http

There is a whole catalog of API mock definitions maintained by Mockoon, which can be found here. Although I suspect that many of the APIs listed there are just publicly available OpenAPI definitions.

Dynamic responses

As you can see, some of the fields in the response are blank, while others are filled in. You can also see that we get different answers in some fields each time. Why is this? Mockoon will automatically generate a dynamic template for us based on the API definition. Let’s have a look at the example below.

Open API definition with enums:

AlbumBase:
...
properties:
album_type:
type: string
description: |
The type of the album.
enum:
- album
- single
- compilation
example: compilation
...
release_date_precision:
type: string
enum:
- year
- month
- day
example: year
description: |
The precision with which `release_date` value is known.
restrictions:
allOf:
- $ref: '#/components/schemas/AlbumRestrictionObject'
description: |
Included in the response when a content restriction is applied.
...

Generated template with enum-based generators:

hmmm… nice. Mockoon understands enums out of the box. It’s not always perfect, and it may need some tweaking.

We can modify this template and add multiple values that will be returned. There are really many, many options in Mockoon. It supports Faker.js and Handlebars. For more details and examples please check out docs.

Partial proxy

Another really great thing about testing APIs with Mockoon is that it can act as a proxy for the real API, overriding responses only if we have defined mock. More info here.

Error simulation

If you’re not familiar with Open API it still should be quite clear. We are looking at albums endpoint which is defined like in the snippet below:

  /albums:
x-spotify-docs-display-name: several-albums
x-spotify-docs-category: Albums
get:
operationId: get-multiple-albums
tags:
- Albums
x-spotify-docs-endpoint-name: Get Multiple Albums
x-spotify-docs-console-url: /console/get-several-albums/
summary: |
Get Several Albums
description: |
Get Spotify catalog information for multiple albums identified by their Spotify IDs.
parameters:
- $ref: '#/components/parameters/QueryAlbumIds'
- $ref: '#/components/parameters/QueryMarket'
responses:
"200":
$ref: '#/components/responses/ManyAlbums'
"401":
$ref: '#/components/responses/Unauthorized'
"403":
$ref: '#/components/responses/Forbidden'
"429":
$ref: '#/components/responses/TooManyRequests'
security:
- oauth_2_0: []

What is interesting here is the responses section. Here we have: ManyAlbums, Unauthorized, Forbidden and TooManyRequests.

This is what Mockoon used to generate our “ManyAlbums” response template that we saw above.

What about errors? Mockoon has got you covered, you can find all the generated errors in the list. You can use the flag icon to change the default response.

List of all generated response templates

So we can choose another response from the list as default to get a 429 error. (Here you can see that the status is 12121 as Mockoon maps number to {{faker ‘datatype.number’}} and we would need to adjust it in our template)

There is no need to return always the same response. There are also options like: random responses, sequential responses (all defined responses in loop).

Scenarios

What if we would like to simulate failures automatically? We don’t want to toggle them all the time. Mockoon has this great feature that can create conditional responses based on request parameters. It supports and/or conditions that can be done based on:

  • Body
  • Query
  • Header
  • Cookie
  • Route params

We can set our albums to return throttle error when it receives header “Scenario” with value “Throttle”

Return throttle based on header value

Let’s check it in action:

Performance tests

Everything we have seen looks like a great engine to simulate many different scenarios. What if we would like to use it for performance testing? We can use the delay function. This is one thing that I’m disappointed about, as it can’t be used with a random range or distribution. Let’s hope it will be added in the future versions (I’ve opened a GitHub feature request for it).

We can setup here response delay per response
We can see that our scenario took >5000ms

Now that we’ve scratched the surface of what Mockoon can do, you might be wondering if it’s just a tool to play with locally. Not necessarily. Your configuration can be exported and shared with others. You can run your specification locally using cli, or… use Docker to deploy it and use it for testing, for example, or even deploy it to the cloud. Let’s have a look.

Docker

First we need to export our configuration to a file:

Right-click on API name and export you config

Then we have to install mockoon-cli with command:

npm install -g @mockoon/cli

Then we can dockerize our API with command:

mockoon-cli dockerize --data ./Spotify.json --port 3000 --output Dockerfile

This command will generate a docker file and our config, which we can even version and upload to ECR using our CI or from a local machine using script:

#!/bin/bash
ACCOUNT_ID=$(aws sts get-caller-identity --output json | jq -r ".Account")
REGION="eu-west-1"
ECR_URL="$ACCOUNT_ID".dkr.ecr."$REGION".amazonaws.com
REPO_URL="$ECR_URL"/spotify-mock

mockoon-cli dockerize --data ./Spotify.json --port 3000 --output Dockerfile
aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin "$ECR_URL"
docker build -t spotify-mock .
docker tag spotify-mock "$REPO_URL"
docker push "$REPO_URL"

Now we can use it in tests using e.g. testcontainers and be agnostic to the language that we are working in and share the mock across many teams if necessary. Of course you can even host that mocked API and deliver that docker image as you want using ECS, EKS, Kubernetes or run it locally.

The dockerize command also supports URLs, so we can build our mock api based on a shared configuration, which could even be stored in a central location such as S3. You can do this with mockoon-cli dockerize --data <url-to-your-definition> --port 3000 --output Dockerfile .

Serverless

You can also easily run your mock definition using Serverless. Currently it’s supported for AWS Lambda and Firebase Functions.

You can take a look on example setup on github, but it’s as simple as:
- creating new lambda with sam init
- adding one dependency with npm install @mockoon/serverless
- copying your definition to handler directory
- implementing lambda handler with as simple code as one below:

import {MockoonServerless} from '@mockoon/serverless'
import mockEnv from "./Spotify.json" assert { type: "json" }

const mockoonServerless = new MockoonServerless(mockEnv)

export const handler = mockoonServerless.awsHandler()

Now after deployment you can call your AWS Lambda mock deployed in the cloud.

What if you would like to have your config centralised? You can always load dynamically mock api defintion on init. Let’s try to load it from S3.

It will be as easy as adding lambda permissions to that S3 bucket and loading data from S3 before handler. We can use top-level await to keep it dread simple.

import {MockoonServerless} from '@mockoon/serverless'
import {GetObjectCommand, S3Client} from "@aws-sdk/client-s3";

const s3Client = new S3Client({region: 'eu-west-1'})
const s3Object = await s3Client.send(new GetObjectCommand({
Key: "Spotify.json",
Bucket: process.env.DEFINITIONS_BUCKET
}))
const mockEnv = JSON.parse(await s3Object.Body.transformToString())
const mockoonServerless = new MockoonServerless(mockEnv)

export const handler = mockoonServerless.awsHandler()

All code examples can be found on github.

Summary

I really like Mockoon. Apart from all the great things related to testing, it feels like a great tool that can be used during a meeting to specify the contract between services. After that it can be available in the cloud in a few moments to not slow down your teams.

Let me know what you think about Mockoon and check out more details on Mockoon website. If you liked it, you can support them by sponsoring project, buying their merch :D, or at least giving them a star on github.

Happy mocking!

--

--