Mock Response
Table Of Contents
Introduction
The mock response middleware allows you to return mock responses for an API endpoint without requiring an upstream service. This can be useful when creating a new API or making a development API available to an external team. Tyk has mock response middleware before we implemented OAS. However, the previous one wasn’t respecting any authentication or any other middleware configured for the endpoint. The new mock response has extended OAS capabilities that respect authentication and other middleware. In this new implementation, there are two ways of adding a mock response to an endpoint.
Using the basic mock response
The basic mock response is the way of defining a response inside the operations section of an OAS API definition and setting response components code, body, and headers. See the following example:
"operations": {
"my-operation-id": {
"mockResponse": {
"enabled": true,
"code": 200,
"body": "mock-response-body",
"headers": {
"mock-header-1": "mock-header-value-1",
"mock-header-2": "mock-header-value-2"
}
}
}
}
Note
If code
is not set, 200
is the default response.
Extract from an OAS specification
This is a second and cool way of defining a mock response for an endpoint. The OAS spec documents response details for an endpoint according to response code and content type. Each response type may have example
, examples
or schema
defined. These can be used as a mock response with Tyk. To enable it, just set fromOASExamples
to true
. For example:
"operations": {
"my-operation-id": {
"mockResponse": {
"enabled": true,
"fromOASExamples": {
"enabled": true
}
}
}
}
fromOASExamples
has more fields to select as a mock response; code
, contentType
, and exampleName
. For example:
"fromOASExamples": {
"enabled": true,
"code": 200,
"contentType": "application/json",
"exampleName": "first-example"
}
Note
If code
is not set, 200
is the default response. If contentType
is not set, application/json
is the default.
exampleName
is only valid where there are examples defined in the response documentation. See below.
With a request, you can override the configured code
, contentType
, and exampleName
. Here are the special headers for it:
Accept
: Overrides the response content type i.e.application/json
,text/plain
. This is a standard HTTP header.X-Tyk-Accept-Example-Code
: Overrides the deafult response code i.e.400
.X-Tyk-Accept-Example-Name
: Overrides the selected example among multiple examples i.e.second-example
.
If an example response can’t be found in the configured code, contentType
or exampleName
, an error will be returned with 404
. For example:
curl --request GET --header 'X-Tyk-Accept-Example-Code: 512'
'http://tyk-gateway:8181/my-api/get'
{
"error": "mock: there is no example response for the code: 512"
}
Extract response code and body
A HTTP response has three main parts; code
, body
, and headers
. Here’s how to extract code and body from an OAS response definition.
In an OAS response definition, there is an example
field showing a possible response when calling this endpoint. Tyk can extract it to use it as a response when fromOASExamples
is set to true
. For example:
{
...
"paths": {
"/get": {
"get": {
"operationId": "getget",
"responses": {
"200": {
"content": {
"application/json": {
"example": "Foo"
}
},
"description": ""
}
}
}
}
},
"x-tyk-api-gateway": {
...
"middleware": {
...
"operations": {
"getget": {
"mockResponse": {
"enabled": true,
"fromOASExamples": {
"enabled": true
}
}
}
}
}
}
}
Sample Request
curl --request GET 'http://tyk-gateway:8181/my-api/get'
"Foo"
Examples
In an OAS response definition, examples
is used to define multiple examples for the same response. It is mutually exclusive with example
. Only one can be selected, example or examples. Both can’t be set at the same time.
Let’s assume that examples
exist. However, if there are multiple examples
added, which one does Tyk select and return? That’s where exampleName
comes in. In the fromOASExamples
, the default exampleName
can be selected. Or you can set it via the request header X-Tyk-Accept-Example-Name
.
Note
The example
name set in the request header overrides the configured one. If the request header and the configuration don’t have it, Tyk will select randomly from the multiple examples
. And, yes, that means the response may change with every request.
{
...
"paths": {
"/get": {
"get": {
"operationId": "getget",
"responses": {
"200": {
"content": {
"application/json": {
"examples": {
"first-example": {
"value": "Foo"
},
"second-example": {
"value": "Bar"
}
}
}
},
"description": ""
}
}
}
}
},
"x-tyk-api-gateway": {
...
"middleware": {
...
"operations": {
"getget": {
"mockResponse": {
"enabled": true,
"fromOASExamples": {
"enabled": true
}
}
}
}
}
}
}
Sample Requests
curl --request GET --header 'X-Tyk-Accept-Example-Name: first-example'
'http://tyk-gateway:8181/my-api/get'
"Foo"
curl --request GET --header 'X-Tyk-Accept-Example-Name: second-example'
'http://tyk-gateway:8181/my-api/get'
"Bar"
Schema
If there is no example
or examples
defined, Tyk will try to find a schema for the response. If there is a schema, it will be used to generate a mock response. Each schema field may have an example field and they can be used to build a mock response.
{
...
"paths": {
"/get": {
"get": {
"operationId": "getget",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"lastName": {
"example": "Bar",
"type": "string"
},
"name": {
"example": "Foo",
"type": "string"
}
}
}
}
},
"description": ""
}
}
}
}
},
"x-tyk-api-gateway": {
...
"middleware": {
...
"operations": {
"getget": {
"mockResponse": {
"enabled": true,
"fromOASExamples": {
"enabled": true
}
}
}
}
}
}
}
Sample Request
curl --request GET 'http://tyk-gateway:8181/my-api/get'
{
"name": "Foo",
"lastName": "Bar"
}
The schema properties may not have example
values. In that situation, the default values are used to build a response. See the following examples for each type:
string
>string
integer
>0
boolean
>true
Using $ref and nested schema
In the above example, the schema was in line. However, Tyk is smart enough to extract values from a referenced or a nested schema object as well. For example:
{
"components": {
"schemas": {
"Engineer": {
"type": "object",
"properties": {
"lastName": {
"example": "Senharputlu",
"type": "string"
},
"name": {
"example": "Furkan",
"type": "string"
}
}
}
}
},
"paths": {
"/get": {
"get": {
"operationId": "getget",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Engineer"
}
}
}
}
}
}
}
}
}
Extract response headers
In the OAS response definition, headers
is used to document the returned headers from that endpoint. Tyk can build the mock response headers with them. headers
don’t have any standalone example
or examples
attributes, it just has schema
. Tyk uses that schema
as in the response body. For example:
{
...
"paths": {
"/get": {
"get": {
"operationId": "getget",
"responses": {
"200": {
"headers": {
"X-Mock-Header": {
"schema": {
"type": "string",
"example": "Foo"
}
}
},
"content": {...},
"description": ""
}
}
}
}
},
"x-tyk-api-gateway": {
...
"middleware": {
...
"operations": {
"getget": {
"mockResponse": {
"enabled": true,
"fromOASExamples": {
"enabled": true
}
}
}
}
}
}
}
Sample Request
curl -I --request GET 'http://tyk-gateway:8181/my-api/get'
HTTP/1.1 200 OK
Content-Type: application/json
X-Mock-Header: Foo <-------- the extracted mock header
X-Ratelimit-Limit: 0
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 0
Date: Fri, 07 Oct 2022 12:11:00 GMT
Content-Length: 42
Connection: close