Request and Response Adapters Commercial
Specmatic's adapters let you transform traffic that comes to the mock or proxy server. They are useful when the provider and consumer speak a wire format that differs in some way from the actual data that traverses the wire.
For example, a consumer may encrypt application/json data in the request sent to the provider. And thus while the data in the request body is JSON (application/json), on the wire after encryption it might be a string (text/plain). You may want the specification to capture the application/json format, rather than text/plain. But if you do, the specification no longer describes the actual traffic on the wire. How then might we record a specification that reflects the format of data processed by the application, while still allowing the consumer and provider to exchange data in the expected wire format?
Adapters
Adapters can bridge that gap between the wire format of the HTTP message and the format of the data as processed by the application. They can act as a translation layer between the wire format and the application format.
Specmatic exposes three adapters that run at different stages of request or response handling. They give you precise control over how traffic is translated between the consumer, Specmatic, and the provider.
They may be registered in specmatic.yaml as shown below:
- Version 3 (recommended)
- Version 2
- YAML
- specmatic.json
version: 3
dependencies:
data:
adapters:
post_specmatic_response_processor: python post_specmatic_response_processor.py
pre_specmatic_request_processor: python pre_specmatic_request_processor.py
pre_specmatic_response_processor: python pre_specmatic_response_processor.py
{
"version": 3,
"dependencies": {
"data": {
"adapters": {
"post_specmatic_response_processor": "python post_specmatic_response_processor.py",
"pre_specmatic_request_processor": "python pre_specmatic_request_processor.py",
"pre_specmatic_response_processor": "python pre_specmatic_response_processor.py"
}
}
}
}
- YAML
- JSON
version: 2
hooks:
post_specmatic_response_processor: python post_specmatic_response_processor.py
pre_specmatic_request_processor: python pre_specmatic_request_processor.py
pre_specmatic_response_processor: python pre_specmatic_response_processor.py
{
"version": 2,
"hooks": {
"post_specmatic_response_processor": "python post_specmatic_response_processor.py",
"pre_specmatic_request_processor": "python pre_specmatic_request_processor.py",
"pre_specmatic_response_processor": "python pre_specmatic_response_processor.py"
}
}
In each case, the value of the adapter entry is the path to an executable file (script or binary) that Specmatic will invoke at the appropriate time.
pre_specmatic_request_processor
- Runs in both proxy and mock modes.
- Receives the incoming request before Specmatic validates it (mock) or forwards it to the provider (proxy).
Use this adapter when the consumer sends payloads in a shape that Specmatic should process as-is.
The adapter should read the request in the Specmatic example format from the stdin, modify it as needed, and write the transformed request back to stdout.
Sample input to the adapter (STDIN):
{
"http-request": {
"method": "POST",
"path": "/api/data",
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": "eyJrZXkiOiAidmFsdWUifQ==" // base64 encoded JSON
}
}
}
Sample output from the adapter (STDOUT):
{
"http-request": {
"method": "POST",
"path": "/api/data",
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": {
"key": "value"
}
}
}
}
pre_specmatic_response_processor
- Runs in proxy mode as responses come back from the real provider.
- Gives you the combined request/response document so you can adjust what Specmatic records.
Sample input to the adapter (STDIN):
{
"http-request": {
"method": "GET",
"path": "/api/data"
},
"http-response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": "eyJzZWNyZXQiOiAiVmFsdWUifQ==" // base64 encoded JSON
}
}
}
Sample output from the adapter (STDOUT):
{
"http-request": {
"method": "GET",
"path": "/api/data"
},
"http-response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": {
"secret": "Value"
}
}
}
}
post_specmatic_response_processor
- Runs only in mock mode, after Specmatic has generated a response for the consumer.
- Lets you re-encode payloads, set protocol-specific headers, or add late-stage metadata before the mock server returns control to the caller.
Use this adapter when the consumer expects something different on the wire (for example base64 or plain text) from what's in the specification.
Sample input to the adapter (STDIN):
{
"http-request": {
"method": "POST",
"path": "/api/data",
"headers": {
"Content-Type": "text/plain"
},
"body": {
"data": "some content"
}
},
"http-response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": {
"secret": "Value"
}
}
}
}
Sample output from the adapter (STDOUT):
{
"http-response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"data": "eyJzZWNyZXQiOiAiVmFsdWUifQ==" // base64 encoded JSON
}
}
}
The configuration is evaluated relative to the directory in which Specmatic is launched. You can point at shell scripts, compiled binaries, or even Node/Python entry points... anything executable on your platform.
Notes On Writing Adapter Scripts
- The script must print the transformed JSON document to STDOUT.
- The script may need to change the
Content-Typeof the request or response if the transformation alters the payload format. - Exit with status
0to let Specmatic continue. Any non-zero status will be detected by Specmatic. The script's output will be printed to the console, and the adapter unprocessed request will be used instead. - Make sure dependencies, language runtimes, etc required by the adapters are available in the environment where Specmatic runs.
- If the adapters are executable scripts, remember to grant execute permissions (
chmod +x adapters/*.sh) so Specmatic can invoke the adapter scripts.
Sample Project
See adapters-demo for a complete, runnable example.