request:
- method: GET
- uriPath: /api/v2/categories
API Simulation Configuration
Overview
If you have not already, make sure to read the Basic Concepts page to get you started.
Then go over the sections below to get an understanding of how to model and configure API simulations and their simlets. Find more in depth documentation on the pages that follow.
DSL for Simulation Modeling
Modeling API simulations via configuration for the Standalone API Simulator is now easier than ever with API Simulator’s unique Domain Specific Language (DSL). The expressive DSL allows us to define simlets using simple and easy to understand constructs.
The DSL makes use of a small subset of the YAML language. Few simple constructs actually: name/value pairs, lists, and maps. Much like JSON but less verbose and easier to use for configurations. Don’t worry if YAML is something new to you - in no time you will be reading and writing simlets.
Here is a small example demonstrating a possible configuration for matching HTTP requests that have "GET" method and particular URI path:
About YAML
YAML (YAML Ain’t Markup Language), per the description on its web site, is a "…human friendly data serialization standard for all programming languages". It has gained wide acceptance as the language of choice for configuration.
YAML uses indentation-based scoping. In general, an element must be indented further than its parent element, and elements at the same level have the same indentation.
Indentation is very important in YAML. The right indentation leads to a well-formed YAML document and proper interpretation of the configuration.
Since v1.7 API Simulator extends the YAML syntax to support multi-line text content that doesn’t have to be indented. That makes configuring text elements like HTTP body content less error-prone.
YAML and JSON
JSON is a subset of YAML 1.2 - a JSON document is also a YAML document.
API Simulator can load simlet configuration in JSON as well. However, the JSON-based DSL will not be documented at this time. While both YAML and JSON can be used for human-friendly representation of data structures, arguably perhaps, YAML is more suitable for configuration and JSON for messaging.
API Simulation Names
Each API Simulation has a name. A simulation name must be a valid subdomain name:
-
Starts with an
a
throughz
letter. -
Then contains letters
a
throughz
, digits0
through9
, and hyphen-
, where hyphen is not the last character. -
Has maximum length of 63.
-
Is case-insensitive.
These rules are currently not enforced; however, following them will assure backward compatibility in the future.
API Simlet Names
Each API simlet has a name. The names follow the rules for valid subdomain name like in API Simulation Names.
Creating a New Simulation
To create a new API Simulation simply create a directory and name it after the name of the simulation. See above for the rules to follow when naming it.
Next, model simulation’s simlets. API Simulator gives you a choice when it comes to organizing the simlets:
-
All-in-one configuration file.
-
Dedicated directory per simlet.
All-in-one Configuration
All simlets of a simulation can be defined in a single file named apisim.yaml
and placed in the simulation’s directory:
api-simulation-name
└─ apisim.yaml
Inside apisim.yaml
, simlet definitions are separated by three dashes ---
on a line:
simlet: <simlet1-name>
<simlet1 definition>
---
simlet: <simlet2-name>
<simlet2 definition>
---
# ....
---
simlet: <simletN-name>
<simletN definition>
Each simlet requires a name followed by the simlet-specific configuration.
The all-in-one configuration file is suitable for small number of simlets with generally smaller response payloads. Otherwise, it becomes difficult to navigate up and down the single, potentially big file.
Directory per Simlet
Another option API Simulator supports is to have a directory per simlet, all under a directory called simlets
:
api-simulation-name
└─ simlets
The configuration for each simlet is placed in a directory named after the simlet and under the simlets
folder. There is always a file named simlet.yaml
, which contains the simlet configuration. For example:
payments-simulation
└─ simlets
├─ create-payment
│ └─ simlet.yaml
├─ get-payment
│ └─ simlet.yaml
├─ list-payments
│ ├─ simlet.yaml
│ └─ large-payments-list.json
└─ not-found
└─ simlet.yaml
In the example above, create-payment
, get-payment
, list-payments
, and not-found
are directories for simlets with those names; each directory has a simlet.yaml
file that contains the definition of that simlet. The list-payments
directory also has another file that is external to simlet.yaml
, presumably with the JSON body of the response.
If there is a simlet with some name in apisim.yaml
and directory with that same name under simlets
then the simlet from apisim.yaml
will not get loaded - the one in simlets
takes precedence.
Using External Files
Both options for organizing the simlets allow the HTTP response body for a simlet to be in an external file. Having a separate file helps with simlets that return binary content (e.g. images) and/or large responses.
External files are also supported for external scripts in scripting.
Aside from using absolute paths to external files, API Simulator supports the following global variables that can be used to represent relative paths to files:
-
${sim.path}
- resolves to the simulation directory. -
${simlets.path}
- points to thesimlets
directory for the simulation.
Here is an example:
simlet: get-favicon
request:
- method: GET
- uriPath: /favicon.ico
response:
from: stub
headers:
- "Content-Type: image/png"
body:
type: binary
file: "${sim.path}/favicon-16x16.png"
In the example above, the favicon-16x16.png
file is expected to be under the simulation directory as given by ${sim.path}
.
Full-blown Directory Structure
Regardless which approach you choose for organizing the simlets, the following optional directory structure can help with simulations that are more complex:
api-simulation-name
├─ bin
├─ config
├─ lib
├─ logs
├─ scripts
└─ simlets
Here is a description of each directory:
Directory | Description |
---|---|
|
This optional directory can be a convenient place for custom scripts to start and stop the simulation. Such scripts could take care, for example, of setting all simulation-specific start and stop arguments. |
|
Custom configuration, like for logging, can be placed in this directory. If the directory is missing, such configs can be placed directly under the simulation’s directory. Optional. |
|
API Simulator is extensible by custom code. Any compiled artifacts placed in this directory will be automatically added to the classpath. Optional. |
|
Log files will be created in this directory, if it exists. Otherwise, the log files will be created directly in the simulation’s directory. Optional. |
|
If one or more of the simlets use scripting to enhance the API Simulator’s capabilities, files with the scripts can be placed in the "scripts" directory. Optional. |
|
Contains configuration for each simlet that is part of the simulation. Optional when using all-in-one simlets configuration file. |
On Request Mismatch
API Simulator matches incoming requests to determine the simlet which response to return. There are two options for when a request cannot be matched:
-
Use a default simlet.
-
Forward the unmatched request.
Default Simlet
To define a default, fallback simlet, create a simlet and give it any valid simlet name; then configure it as matching any request:
request: any
response:
from: stub
status: 400
body: "What are you doing?"
The response can be anything, including a dynamic response from template.
If an API simulation does not define a default simlet and a request cannot be matched, API Simulator will use its built-in default simlet. It returns "404 Not Found" for HTTP status and "API Simulator couldn’t find a matching simlet for the request." for body.
Request Forwarding
For request forwarding to work, API Simulator must be called as a HTTP or HTTPS proxy for the calling API client. This way, requests will be sent to API Simulator and will contain the actual destination host. If a request matches a simlet, API Simulator will return the response; if a request does not match a simlet, the request will be forwarded unchanged to the actual destination, and the response relayed back. In essence, API Simulator will be a pass-through for unmatched requests.
This functionality is currently not exposed via the DSL. See the Command-line Arguments for how to configure API Simulator to forward unmatched requests.
We would love to hear your feedback! Shoot us an email to [feedback at APISimulator.com] about anything that is on your mind.
Happy API Simulating!