Skip to content

Repository files navigation

Sim

Gogoreleaser

Why

Makes API simulation easy and fast.

What

Sim is straight-forward API simulation tool that's tiny, fast, secure and scalable.

Sim turns OpenAPI specs into executable API specs.

Sim doesn't just mock APIs, it allows you to specify scripts for each API operation which have access to a key-value database that allows APIs to save state between requests.

Most of today's API mocking tools run in virtual machines such as the JVM or NPM. Sim is a single binary with zero dependencies.

  • It's orders of magnitude smaller binary and memory usage. Which much lower CPU usage. Each process can simulation multiple APIs.
  • Running on Kubernetes? Three pods could simulate every API in your organization with high-availability.

Sim was written with extensive help from AI.

Install

Like jq, sim is a tiny (16Mb) standalone binary. You can download it from the releases page.

If you're on MacOS, you can use brew:

brew tap kitproj/sim --custom-remote https://github.com/kitproj/sim
brew install sim

Otherwise, you can use curl:

curl -q https://raw.githubusercontent.com/kitproj/sim/main/install.sh | sh

We do not support go install.

As Docker image:

docker run --rm -ti -v examples:/apis ghcr.io/kitproj/sim

Usage

Create a directory containing files named *.yaml.

Then run:

sim apis

Mocking

Simulations are described by their API specification. For simple mocking, specify your examples in the OpenAPI spec:

openapi: 3.0.0info:
title: Hello APIversion: 1.0.0servers:
- url: http://localhost:8080paths:
/hello:
get:
responses:
'200':
description: OKcontent:
application/json:
example: { "message": "Hello, world!" }

Scripting

openapi: 3.0.0info:
title: Teapot APIversion: 1.0.0servers:
- url: http://localhost:4040# This script is executed when the spec is loaded.# You can use it to specify global variables and functions that are available to all scripts.x-sim-script: | var status = 418paths:
/teapot:
get:
# This script is executed whenever the request is serviced.# The last variable is the response object.x-sim-script: | response = { "status": status, "headers": { "Teapot": "true" }, "body": { "message": "I'm a teapot" } }responses:
'200':
description: OK

Scripting With A Database

openapi: 3.0.0info:
title: Document APIversion: 1.0.0servers:
- url: http://localhost:4040paths:
/documents:
post:
x-sim-script: | var uuid = randomUUID(); db.put("/documents/" + uuid, request.body) response = { "status": 201, "headers": { "Location": "/documents/" + uuid } }responses:
'200':
description: OKget:
x-sim-script: | response = { "body": db.list("/documents") }responses:
'200':
description: OK/documents/{id}:
get:
parameters:
- name: idin: pathrequired: trueschema:
type: stringx-sim-script: | var document = db.get("/documents/" + request.pathParams.id); if (document) { response = { "body": document } } else { response = { "status": 404, } }responses:
'200':
description: OKdelete:
parameters:
- name: idin: pathrequired: trueschema:
type: stringx-sim-script: | db.delete("/documents/" + request.pathParams.id) response = {}responses:
'204':
description: OK

Scripting With HTTP Requests

A script can make a HTTP request:

#!/usr/bin/env simopenapi: 3.0.0info:
title: Proxy APIversion: 1.0.0servers:
- url: http://localhost:5050paths:
/proxy:
get:
x-sim-script: | hello = http({"url": "http://localhost:8080/hello"}) response = { "status": hello["status"], "headers": { "Proxy": "true" }, "body": hello.body }responses:
'200':
description: OK

Executable Specs

You can make you spec an executable program, add the following line:

#!/usr/bin/env sim

Make your YAML executable with chmod +x.

Reference

In you script you have access to the following:

request

An object containing the HTTP request, e.g.

{
"method": "PUT",
"path": "/documents/bar",
"pathParams": {
"id": "bar"
},
"queryParams": {
"foo": "bar"
},
"headers": {
"Content-Type": "application/json"
},
"body": {
"baz": "qux"
}
}

For example:

varbody=request.body;

randomUuid()

A function that generates a random UUID. For example:

varuuid=randomUUID();

db

A service that allows you to persist and access data:

// get an object, maybe nullvarvalue=db.get(key);// put an object (idempotent)varexisted=db.put(key,value);// delete an object (idempotent)vardeleted=db.delete(key)// return an array of all objectsvarlist=db.list(keyPrefix);

For example:

varobj=db.get("/my-api/"+id)if(obj){response={status: 404}}else{response={body: obj}}

About

Straight-forward tiny fast API Simulation

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages