Creating Mock Instances with Blackbird
Mocking API Endpoints enhances productivity, facilitates testing and improves the overall quality of the application. Quickly spin up a mocking instance that enables parallel development of frontend and backend components by allowing developers to work on their respective parts simultaneously.
If you have your own examples included in your OpenAPI specification, you can use those as well by passing in the
Prefer: dynamic=false
header to requests to your mock API server.
Deploying a new Mock API requires the use of OpenAPI Specification Version.
Create a new Mock
If you have an existing API Service in our API catalog, you can use its slug name to spin up a new mock server. You can learn more about creating a new API in the Blackbird catalog here.
Alternatively, you can download the sample petstore.yaml file to test with or use your own.
Delete a Mock
To delete a running mock, you can run the mock delete command to remove it.
List Mocks
To see a list of all active mocks, you can run the list deployments command.
Secure a Mock
By default the mock endpoints are available to the public. In order to secure these endpoints we can use APIKeys. We can also create and set an APIKey on creation with the --apikey-header
flag.
Configure a Mock
After creating a mock, you can dynamically adjust it's configuration by using the mock config <mock-name> set
command.
To preview the configuration of your mock instance, you can use the mock config <mock-name> get
command.
At the moment, dynamic
is the only configuration value that can be set.
Set dynamic data generation
Your mock instance will have a default configuration that will generate random data based on the schema objects defined in the OpenAPI specification. If you have examples defined throughout your OpenAPI specification, you might want to disable the dynamic data generation.
Troubleshooting
Unable to enforce a specific error response
In order to enforce a specific error response, you need to specify the Prefer
header with a respective code
value.
This would make our mock server prefer a 404
error response from the list of responses defined in the OpenAPI specification.
Mock Server does not use my examples
By default, the mock server will return dynamic data generated based on the Schema Objects defined in the OpenAPI specification.
If you have your own examples included in your OpenAPI specification, you can use those as well by passing in the Prefer: dynamic=false
header to requests to your mock server.
You can also combine it with the Prefer: code
header to enforce a specific error response.
Mock Server returning unexpected data / objects with weird properties
If you are seeing unexpected data or objects with weird properties, it is likely your OpenAPI definition is not imposing restrictions on the data.
In this example, the schema defines an object with a required name
property that is to be a string, but it does not restrict any other properties.
As such, the mock server is free to return any object that has a name
property that is a string, but may also have other properties.
In Schema Objects, regardless of the version of the OpenAPI, there is a keyword called additionalProperties
that can be used to define the behavior of unspecified properties.
This schema will only accept objects that have a name
property that is a string and no other properties.
You can also specify a different Schema Object if you do expect extra properties, i.e. if you want to have a dictionary.
This schema will only accept objects that have a name
property that is a string and any other properties that are strings.
Bear in mind that this may have implications if you reference this schema in other parts of your OpenAPI definition. Since there is no notion of inheritance in Schema Objects, you may have to copy the schema or adjust the "base" schema to accommodate the new restrictions.
That is particularly common if you have a "base" schema that you try to combine with others using "allOf".
The above schema is semantically wrong and will always evaluate to false regardless of the input provided.
That is because each child schema in allOf
is applied in isolation against the piece of input.
Say we have this input:
Now, if we take the "User" schema and apply it to the input, it will evaluate to false, since "age" is not expected to be there. If we take the second schema and apply it to the input, it will also evaluate to false, since "name" is not expected to be there.
If you do not want to copy the schema, you can try extending the "base" schema.
While the above slightly changes the behavior of the User schema, the root schema now correctly evaluates to true for the input provided, while disallowing any extra properties.
There is a better aid to that in OpenAPI 3.1.0, assuming you use the json schema dialect 2019-09 or newer, namely unevaluatedProperties
to enforce that no properties are allowed that are not defined in the schema.
My payload seems correct, but I'm getting 422
Make sure your Schema Objects are defined correctly.
As already mentioned in a few previous examples, our definition may seem correct, but gets evaluated to false
when the mock server tries to validate it.
While it is not feasible to list all possible instances where this might happen, here is a list of a few examples:
The above Schema is quite open-ended, and the range of compliant inputs is very narrow.
This is because oneOf
acts as a logical XOR
operator, meaning the input must match exactly one of the schemas.
That on its own is not an issue, but usually when the sub schemas themselves are restrictive, which is not the case here.
The first schema accepts any object as long as its name
property is of a string.
In practice, the only invalid input would be an object with a name
property that is not a string.
The second schema is no different - the only invalid input would be an object with an age
property that is not a number.
As one sees, there's a large set of overlapping data, and as such it is easy to author an invalid input.
Another common issue is when allOf
is used to "combine" schemas.
In practice, allOf
acts as a logical AND
operator, meaning the input must match all child schemas.
It does not extend or inherit the schema that is referenced, not does it override any constraints the referenced schema introduces.
For more details on specific errors that you might encounter when mocking, please take a look at the Mock Server Errors reference page.