mockgo-server is a lightweight http server which can be used to mock http endpoints. mockgo-server is designed for horizontal scaling and feels at home in cloud environments like kubernetes and knative. The main features are:
See Examples.md.
mockgo-server is built with different variants which have their own use cases. The following table gives an overview:
variant | can scale | persistence | use this when you ... |
---|---|---|---|
mockgo-standalone |
no | no | want a simple setup and you don't need to scale, usually this variant is the starting point |
mockgo-grpc |
yes | no | have to deal with high incoming traffic, but you don't need durability for states and results |
mockgo-redis |
yes | yes | have to deal with high incoming traffic and you want a durable storage for states and results or if you want to use mockgo as serverless deployment in knative |
Kubernetes is the first class environment for mockgo-server. So, if you have kubernetes cluster available, you can start right away with helm charts:
helm repo add mockgo-server https://alitari.github.io/mockgo-server/
helm upgrade mymock mockgo-server/mockgo-server --install
see here for further helm configuration options.
If you have a knative cluster available, you can start right away with kn
cat <<EOF > kn-mock.yaml
endpoints:
- request:
path: "/hello-kn"
response:
statusCode: 200
body: "Hello from knative"
EOF
kubectl create configmap mockgo-config --from-file=kn-mock.yaml
kn service create mockgo --image=alitari/mockgo-standalone:v1.3.0 --mount /mockdir=cm:mockgo-config --env MOCK_DIR=/mockdir --env MOCK_PORT=8080
MOCKGO_URL=$(kn service describe mockgo -o url)
curl -v $MOCKGO_URL/hello-kn
See here for a example with redis.
Define the environment :
MOCKGO_RELEASE_VERSION="v1.3.0"
MOCKGO_VARIANT="standalone" # or "grpc"
MOCKGO_OS="linux" # or "windows"
MOCKGO_ARCH="amd64" # or "arm64"
MOCKGO_NAME=mockgo-${MOCKGO_VARIANT}-${MOCKGO_OS}-${MOCKGO_ARCH}
wget https://github.com/alitari/mockgo-server/releases/download/$MOCKGO_RELEASE_VERSION/$MOCKGO_NAME
chmod +x $MOCKGO_NAME
# MOCK_DIR is the path for looking for mockfiles, per default this are files with names matching "*-mock.*"
MOCK_DIR=$(pwd)/test/mocks ./$MOCKGO_NAME
go install github.com/alitari/mockgo-server/mockgo-$MOCKGO_VARIANT/starter/mockgo@latest
MOCK_DIR=$(pwd)/test/mocks mockgo
MOCK_DIR=$(pwd)/test/mocks
docker run -it -v $MOCK_DIR:/mocks -e MOCK_DIR=/mocks alitari/mockgo-$MOCKGO_VARIANT:$MOCKGO_RELEASE_VERSION
A mockgo-server configuration consist of one or multiple files in yaml format, the so called mockfiles. Each mockfile contains one or multiple endpoints. The endpoint defines criteria which qualify the endpoint to serve an incoming request. This process is called matching. The second configuration part of an endpoint is the definition of the http response.
endpoints:
- id: "id" # [OPTIONAL] unique string to identify endpoint
prio: 1 # [OPTIONAL] integer to define precedence of endpoints if more than one endpoint matches
request: # request defines the matching
host: "alexkrieg.com" # [OPTIONAL], match to http host
method: "POST" # [OPTIONAL], match to http method, default is "GET"
path: "/mypath" # [MANDATORY], match to http request path
query: # [OPTIONAL] for matching, every key value pair must be part of the http query parameters of the incoming request
firstQueryParam: value1
secondQueryParam: value2
headers: # [OPTIONAL] for matching, every key value pair must be part of the http header values of the incoming request
Content-Type: "application/json"
Myheader: myheaderValue
body: "^{.*}$" # [OPTIONAL] regular expression which match to the request body
response: # defines the response
statusCode: 204 # [OPTIONAL], http response code ( see RFC 7231), defaults to "200"
body: "hello" # [OPTIONAL], response body as string, templates can be used
bodyFilename: "response.json" # [OPTIONAL], refers to a file which contains the response body, templates can be used in the file
headers: | # [OPTIONAL],multiline string in form of key: value, templates can be used
Content-Type: "application/text"
The form of a http request can be described as a sequence of pathsegments which are separated through a /
. In order to achieve flexibility matching the path of an http request, there are 3 special symbols which can be used for the pathsegment defining the request.path
:
*
every pathsegment on this position matches{pathvariable}
every pathsegment on this position matches, the value of the pathsegment is available as template variable with name pathvariable
**
one or more arbitrary pathsegments match on this positionrequest.path |
incoming request path | match |
---|---|---|
/foo/* |
/bar |
➖ |
/foo/* |
/foo |
➖ |
/foo/* |
/foo/bar |
✅ |
/foo/* |
/foo/bar/foo |
➖ |
/foo/*/bar |
/foo/bar |
➖ |
/foo/*/bar |
/foo/bar/bar |
✅ |
/foo/{foo}/bar |
/foo/bar/bar |
✅ {{ RequestPathParams.foo }} resolves to bar |
/foo/*/{bar} |
/foo/bar/bar/foo |
➖ |
/foo/*/{bar} |
/foo/bar/bar |
✅ {{ RequestPathParams.bar }} resolves to bar |
/foo/** |
/foo/ |
➖ |
/foo/** |
/foo/bar |
✅ |
/foo/** |
/foo/bar/1/2/3 |
✅ |
/foo/**/{bar} |
/foo/bar/1 |
✅ matches but {{ RequestPathParams.bar }} does not resolve |
/foo/**/foo/{bar} |
/foo/bar/foo |
➖ |
/foo/**/foo/{bar} |
/foo/bar/1/2/foo/3 |
✅ {{ RequestPathParams.bar }} resolves to 3 |
In order to implement program logic, you can use go templates for creating dynamic responses.
The templating mechanism is available for the response.body
and response.headers
attributes and provides following additional functions for:
Request
variablestemplate variable | type |
---|---|
RequestPathParams |
map[string]string |
RequestUrl |
string |
RequestPath |
string |
RequestHost |
string |
RequestBody |
string |
RequestBodyJSONData |
map[string]interface{} |
There are 2 parameters which identifies a value in the key-value store:
store
is a string which identifies the storekey
is a string which identifies the value in the storetemplate function name | signature | description |
---|---|---|
kvStoreGet |
func(store, key string) interface{} |
get the value from store store , which is stored under the key key |
kvStorePut |
func(store, key string, value interface{}) |
store value value under the key key in the store store |
kvStoreRemove |
func(store, key string) |
remove the value under the key key from store store |
The mockgo-server holds multiple kinds of state:
All states can be accessed through an REST api.
The api is secured with basic auth which can be configured with the environment variables API_USERNAME
and API_PASSWORD
.
In order to avoid conflicts with the mock endpoints, the api is exposed under the path prefix /__
.
This can be changed with the environment variable API_PATH_PREFIX
.
method | path | description |
---|---|---|
POST |
/__/reload |
reload the mock files from the mock dir |
The request storage has a limited capacity which can be configured with MATCHES_CAPACITY
.
method | path | description |
---|---|---|
GET |
/__/matches/{endpointId} |
returns all requests which matched to an endpoint |
GET |
/__/matchesCount/{endpointId} |
returns the count of requests which matched to an endpoint, is not limited through capacity |
GET |
/__/mismatches |
returns all requests which didn't match to an endpoint |
GET |
/__/mismatchesCount |
returns the count of all requests which didn't match to an endpoint, is not limited through capacity |
DELETE |
/__/matches/{endpointId} |
deletes storage of all requests which matched to an endpoint |
DELETE |
/__/mismatches |
deletes storage of all requests which didn't match to an endpoint |
Using the path /__/kvstore/{store}/{key}
you can access the key-value store with the following methods:
PUT
stores the content of the request body under the key key
in the store store
GET
returns the content which is stored under the key key
in the store store
DELETE
removes the content which is stored under the key key
in the store store
The mockgo-server exposes besides of the standard go metrics the following application specific counters:
matches{"endpoint":"<endpointId>"}
: Number of matches of an endpointmismatches
: Number of requests which did not match to on endpointFor local development it is useful to have a way to reload the mock files without restarting the mockgo-server. This can be achieved by sending a POST
request to the reload endpoint. This functionality can be combined with a file watcher to automatically reload the mock files when they change. The script scripts/watchmocks.sh
implements this functionality.
# watch for changes in test/main and reload the mock files
./scripts/watchmocks.sh test/main
Learn how to contribute here