Contexts
Contexts are organized in YAML files which act more like namespaces or collections of contexts.
Usually, file names should correspond to the name of the service or the domain.
For example, payments
, or petstore
.
On the filesystem, contexts stored with the provided name and yml
extension in the contexts
directory.
For example, contexts/payments.yml
.
Only individual primitive properties replaced during content generation.
So, you cannot substitute property with an object or a list.
Contexts structure¶
Inside the context file you should provide the data that corresponds to your schema.
For example, if you have an OpenAPI schema with the following structure:
Pet:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
tag:
type: string
Our petstore.yml
context file could look like this:
id: 123e4567-e89b-12d3-a456-426614174000
name: "doggie"
tag: "dog"
So, in case of json
response, the replacement will look like this:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "doggie",
"tag": "dog"
}
Any Schema that has these properties will be replaced with the provided values.
So, the provided context is more like hardcoded-values.
Let's look at another Schema with nested properties:
PetWithOwner:
type: object
properties:
pet:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
tag:
type: string
ownerPerson:
type: object
properties:
id:
type: integer
name:
type: string
It's clear that using name as doggie
is not ideal here.
Our context file could look like this:
pet:
id: 123e4567-e89b-12d3-a456-426614174000
name: "doggie"
tag: "dog"
owner_person:
id: 1
name: "Jane Doe"
The keys inside context files should be snake_case
.
Our response would look like:
{
"pet": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "doggie",
"tag": "dog"
},
"owner_person": {
"id": 1,
"name": "Jane Doe"
}
}
Dynamic keys and values¶
We use the fake
library to generate random values.
You can use it inside your context files to generate dynamic values:
pet:
id: "fake:uuid4"
name: "fake:pet.name"
tag: "fake:gamer.tag"
owner_person:
id: "fake:u_int8"
name: "fake:person.name"
All available fakes
are shipped with the distribution.
contexts/fakes
file has the full list.
The syntax is fake:path.with.dot
.
It is possible to use not only dynamic values but dynamic keys as well:
_id$: "alias:fake.u_int8"
_email$: "alias:fake.internet.email"
Any property in the schema that ends with _id
, _email
, (in case of camelCase Id
, Email
) in its name will be replaced with the generated value.
For example:
{
"userId": 123,
"userEmail": "jane.doe@example.com"
}
Context reuse¶
It is possible to reuse contexts in other contexts.
Let's say we have context files with the following content:
id: "fake:uuid4"
name: "fake:pet.name"
tag: "fake:gamer.tag"
id: "fake:u_int8"
name: "fake:person.name"
We can refer to any property in any context file using alias
keyword:
id: "fake:uuid4"
name: "fake:pet.name"
tag: "fake:gamer.tag"
owner_id: "alias:person.id"
owner_name: "alias:person.name"
id: "fake:u_int8"
name: "fake:person.name"
pet_id: "alias:petstore.id"
pet_name: "alias:petstore.name"
The syntax is alias:<context-file>.<dotted.path>
.
Some commonly used alias located in contexts/common
file
If the alias
won't point to any target property, it will be used as-is, so you can notice the issue.
Other keywords¶
Along with alias
and fake
keywords, there are some other keywords that can be used in context files.
botify
¶
Replaces value with the letters ???
and the number ###
.
For example,
password: "botify:???###"
abc123
.func
¶
Allows to use custom functions to generate values.
There are currently no such functions but they can appear here when needed.
Predefined values¶
To replace property only with predefined set of values we can use list of values instead of single value.
name: ["Jane", "John"]
or
name:
- "Jane"
- "John"
Random value will be picked from a list in this case.
Path and Headers¶
Values replacement for path
and headers
can be used with different dedicated context.
in-path:
pet_id: "alias:fake.u_int8"
id$: "alias:fake.u_int8"
in-header:
x_pet_name: "alias:fake.pet.name"
These contexts will takes precedence over the default context replacements.
The in-
prefix can be changed in the config.yml
file:
app:
# ...
contextAreaPrefix: "in-"
Wiring¶
The filenames are completely arbitrary, and there's no magic involved in regards to which contexts are used for any particular service.
You need to set the corresponding configuration manually in the config file or using the UI.
Each distribution ships with the defaults contexts, in case there's no configuration for service provided - default will be used.
Let's say we have a petstore
service and 2 contexts:
pet:
dog: "fake:"
cat: "fake:"
name: "fake:"
payments:
# ... mappings
people:
# ... mappings
id: "fake:u_int8"
name: "fake:person.name"
Fake file is unnecessary big, we can use just a portion of it:
services:
petstore:
# the name of the context to use when substituting the values in the request/response.
contexts:
- fake: pet
- fake: people
- person:
Only 2 maps will be taken from fake
context and complete person
context will be used.
Replacement will be applied in the order of definition.
Using in Fixed Responses¶
Contexts can be used in fixed responses as well.
Fixed response is the file with contents that you provided, usually with a json
contents, for example:
{
"id": 123,
"name": "doggie",
"tag": "dog"
}
In order to use contexts in fixed responses, we would need to wrap the values in {}
brackets regardless of the value type.
{
"id": "{id}",
"name": "{name}",
"tag": "{tag}"
}
With a context of:
id: 123
name: "doggie"
it will be replaced with:
{
"id": 123,
"name": "doggie",
"tag": "some-string-value"
}
The types will be correctly resolved as well: id
is unsigned int8.
It's possible to use multiple placeholders in a single value:
{
"id": 123,
"nameWithId": "{name}-{id}"
}
will be replaced with:
{
"id": 123,
"nameWithId": "doggie-123"
}