A simple HTTP mocking server.
It is controlled completely via API calls and can be deployed to Cloud Run.
Uses Firestore to persist mock mappings.
There is no authorisation of any kind. Never run this service publicly
available (like with allUsers
, allAuthenticatedUsers
).
go run server.go
# or
make run
To set a rule, POST a properly structured rule json to /mockmate-mappings
.
# set a simple rule for '/'
# set a simple rule for '/json'
curl -d '{"rule": {"path":"/json"}, "response": {"json_body": ["Hello JSON\n"]}}' \
http://localhost:8080/mockmate-mappings
# abuse text body and fill it with escaped json
curl -d '{"rule": {"path":"/json-as-text"}, "response": {"text_body": "[\"Hello JSON\\n\"]"}}' \
http://localhost:8080/mockmate-mappings
# sets a rule that applies to path '/re' and checks if the string 'foo' occurs in the body.
curl -d '{"rule": {"path":"/re", "text_body_regex": ".*foo.*"}, "response": {"text_body": "REGEX OK\n"}}' \
http://localhost:8080/mockmate-mappings
Given the complexity of things like this, you will likely want to script this rule setting.
$ curl http://localhost:8080/
Hello World
$ curl http://localhost:8080/json
["Hello JSON\n"]
$ curl http://localhost:8080/json-as-text
["Hello JSON\n"]
$ curl -d 'i am a foo' http://localhost:8080/re
REGEX OK
$ curl -d 'i am a bar' http://localhost:8080/re
404 page not found
You can record a call to another service with a POST
to /mockmate-mappings:record
. This will return the request and the actual
response. The latter can be used to create a mapping.
$ curl -d '{"scheme": "https://www.example.com", "path": "/foo"}' \
http://localhost:8080/mockmate-mappings:record
{
"request": {
"method": "GET",
"path": "/foo"
},
"response": {
"content_type": "text/html; charset=UTF-8",
"text_body": "... lots of html ...",
"status_code": 200,
"headers": {
"Age": ["421638"],
"Cache-Control": ["max-age=604800"],
"Content-Type": ["text/html; charset=UTF-8"],
"Date": ["Thu, 10 Jun 2021 21:34:32 GMT"],
...
}
}
}
The complete record request syntax:
{
"scheme": "the protocol, host name and port",
"method": "the method",
"path": "the path",
"query_params": {
"key": [
"value1",
"value2"
],
"key2": [
"value3"
]
},
"text_body": "string body",
"headers": {
"key": [
"value1",
"value2"
],
"key2": [
"value3"
]
}
}
}
To see all rules, send a GET to http://localhost:8080/mockmate-mappings
.
curl http://localhost:8080/mockmate-mappings
To clear all rules, send a DELETE to http://localhost:8080/mockmate-mappings
.
curl -X DELETE http://localhost:8080/mockmate-mappings
A mapping consist of a rule and a response. If a request matches with a rule, its linked response is returned. If no rules match, a 404 Not Found is returned.
You can set multiple fields in a rule. These are combined with logical AND.
You can add a priority to a rule. When multiple rules match, the rule with the highest priority wins. When there are ties, one of them will be selected at random.
{
"update_time": "set by server",
"rule": {
"priority": "integer value, higher value = higher priority (not a string)",
"methods": [
"subset of",
"GET",
"POST",
"etc etc",
"empty = all are OK"
],
"path": "url path, mutually exclusive with path_regex",
"path_regex": "url path regex, mutually exclusive with path",
"text_body_regex": "text body regex",
"headers": {
"key": [
"value1",
"value2"
],
"key2": [
"value3"
]
},
"query_params": {
"key": [
"value1",
"value2"
],
"key2": [
"value3"
]
}
},
"response": {
"content_type": "response content type header",
"text_body": "response text body",
"json_body": {
"some": "json object"
},
"bytes_body": "response byte array",
"status_code": "integer status code (not a string)",
"headers": {
"key": [
"value1",
"value2"
],
"key2": [
"value3",
"value4"
]
}
}
}
[Untested]
You can use Cloud Build to create an image.
make build-async
[Untested] You can use Terraform to deploy the service.
- You cannot update existing rules; too much hassle for too little gain. So automate (script, ...) your rule uploading and just rebuild everything on error.
- There are no checks on conflicts between rules.
- By design, there are also no checks if something makes sense in HTTP terms. You might need to mock a really weird service.
- If a recorded call returns JSON, it is returned as (escaped) text
- Always assumes outgoing recorded call body are strings in UTF-8
- Add support for headers in mapping rules