killgrave is a free, open source api development & testing project written in Go and released under MIT. It has 563 GitHub stars, 100 forks and 34 open issues, and was last pushed 5 hours ago. On this registry it ranks #177 of 188 tracked projects in API Development & Testing, with 5 head-to-head comparisons available.

What is killgrave?

Killgrave is an MIT-licensed HTTP API simulator — a mock server written in Go — for developers and testers who need to stand up fake HTTP endpoints from JSON and YAML configuration files instead of learning another tooling language.

What it is

Killgrave is a Go application that simulates HTTP-based APIs. Its central concept is the imposter: a configuration file, identifiable by the .imp.json extension, that defines the rules determining how the server responds to a given request. Configuration can be supplied either through command-line flags or through a config file, and the project deliberately relies on json and yaml so that no separate configuration language has to be learned. The tool is distributed as a Homebrew formula, as a Docker image on Docker Hub, and as source that can be compiled directly, which places it firmly in the Go tooling ecosystem while remaining usable by teams who never write Go themselves.

The problem it solves is the gap between an API contract and a running service. When a backend is unfinished, unstable, or expensive to exercise, Killgrave supplies a server that answers requests according to rules written in ordinary JSON. Because it can validate incoming requests against JSON schemas, check request headers, and match parameters with regular expressions, the simulated server can be made strict enough to catch client-side mistakes rather than merely returning a fixed payload. It also covers the awkward cases that plain stub handlers usually ignore: response delays that imitate network trouble or high load, configurable response headers, CORS, and a proxy mode that forwards to the original server.

Key capabilities

  • Imposter files written in JSON and identified by the .imp.json extension define the request-matching and response rules.
  • Request validation against JSON Schema, plus validation of request headers.
  • Regular expressions in headers and URLs, so a single imposter can accept varying parameters.
  • Custom static and dynamic response bodies across all content types, including application/json, text/html, text/plain and image/jpeg.
  • Configurable response headers and CORS configuration.
  • Response delays on imposters to simulate network issues and high server load.
  • A configurable proxy server mode that calls through to the original server, plus a watcher that reloads the mock server when configuration files change.

Who uses it and how

  • Backend and frontend teams use it to keep client development moving while the real API is still being built, matching requests against imposters instead of waiting on a deployed service.
  • The README states the tool is used by some companies in production environments, despite its pre-1.0.0 versioning.
  • Mac users install through Homebrew, while container-based workflows run the friendsofgo/killgrave image with a volume mount for the working directory, as in the documented docker run -it --rm -p 3000:3000 -v $PWD/:/home -w /home friendsofgo/killgrave --host 0.0.0.0 invocation.
  • The proxy mode suits teams that want to record or intercept traffic against the original server, and the watcher suits iterative local work where imposter files change frequently.

Getting started

Install with brew install friendsofgo/tap/killgrave on macOS, or run the published Docker image friendsofgo/killgrave with port 3000 published and the current directory mounted into the container. Building from source is also documented for other platforms.

How it compares

The provided facts do not name any alternative or paid product that Killgrave is positioned against, so no licence, hosting or cost comparison can be drawn here; on this registry page it stands alone in the mock-server category. What can be said is simply what the README describes: an MIT-licensed, self-hosted binary that configures mocks in JSON and YAML rather than a dedicated tooling language.

When to use it — and when not to

Choose Killgrave when the need is a self-hosted HTTP mock that a team can configure in files it already understands and run as a single binary or container. Be aware that it is pre-1.0.0: minor version numbers signal breaking changes and patch numbers cover non-breaking changes and bugfixes, so pinning and upgrade testing matter. The Homebrew formula always delivers the latest release, which the README notes as a known limitation, and with 34 open issues and no SemVer stability guarantee yet, teams needing a frozen, contract-stable mock layer should weigh that before adopting it.

project readme (upstream, from github) — read inline

Golang Killgrave

Killgrave

Killgrave is a simulator for HTTP-based APIs, in simple words a Mock Server, very easy to use, made in Go.

Github actions Version Go Report Card FriendsOfGo

Table of Content

Overview

Killgrave is a tool that provides a simple way to create a powerful simulator for HTTP-based APIs.

The Killgrave's philosophy is to provide an easy way to configure your mock server, ensuring that you don't need to learn another tooling language. For that reason we use json and yaml to generate all necessary configurations.

Killgrave provides:

  • An easy way to create imposters files, using json
  • The possibility to validate requests against json schemas.
  • Validation of request headers.
  • Using regex to allow different parameters in headers and urls.
  • Custom body and dynamic body responses.
  • Using all content-types bodies, (application/json, text/html, text/plain, image/jpeg, etc. )
  • Configure response headers.
  • Configure CORS.
  • Simulate network issues and server high loads with imposter responses delay.
  • Using configurable proxy server to call to the original server.
  • Run the tool using flags or using a config file.
  • Run your mock server using a watcher to reload on configuration changes.

Concepts

Imposters

Imposters are the most important concept of the Killgrave tool. They define the rules that determine how the server should respond to a request.

You can identify a Killgrave imposter file by its extension: .imp.json.

You can learn more about how to configure imposters in the Imposter Configuration Section.

Installing

:warning: Even though Killgrave is a very robust tool and is being used by some companies in production environments, it's still in initial development. Therefore, 'minor' version numbers are used to signify breaking changes and 'patch' version numbers are used for non-breaking changes or bugfixing. As soon as v1.0.0 is released, Killgrave will start to use SemVer as usual.

You can install Killgrave in different ways, but all of them are very simple:

Homebrew

If you are a Mac user, you can install Killgrave using Homebrew:

$ brew install friendsofgo/tap/killgrave

:warning: If you are installing via Homebrew, you always get the latest Killgrave version, we hope to fix this soon.

Docker

The application is also available through Docker.

docker run -it --rm -p 3000:3000 -v $PWD/:/home -w /home friendsofgo/killgrave --host 0.0.0.0

-p 3000:3000 publishes port 3000 (Killgrave's default port) inside the container to port 3000 on the host machine.

--host 0.0.0.0 is necessary to allow Killgrave to listen and respond to requests from outside the container (the default, localhost, will not capture requests from the host network).

Compile by yourself

If you want to use Killgrave from the source code, first you will need to clone the repository:

git clone git@github.com:friendsofgo/killgrave.git

Select the branch you want to use (main by default), and then compile Killgrave:

make build

This command will create an executable into the path bin/killgrave. We highly recommended the usage of this command to compile the software because parameters such as version are added to the compilation, which are necessary when reporting a bug.

Other

Windows and Linux users can download binaries from the Github Releases page.

Getting Started

To start Killgrave, you simply run the following.

$ killgrave

While you are welcome to provide your own configuration, Killgrave will default to the following configuration:

  • imposters path: imposters
  • host: localhost
  • port: 3000
  • CORS: []
  • proxy: none
  • watcher: false

Using Killgrave from the command line

Killgrave takes the following command line options. Killgrave is almost fully configurable through the command line, except for CORS, which can only be configured using the config file.

$ killgrave -h

Simple way to generate mock servers

Usage:
  killgrave [flags]

Flags:
  -c, --config string       Path to your configuration file
  -h, --help                Help for Killgrave
  -H, --host string         Set a different host than localhost (default "localhost")
  -i, --imposters string    Directory where your imposters are located (default "imposters")
  -P, --port int            Port to run the server (default 3000)
  -m, --proxy-mode string   Proxy mode, the options are all, missing or none (default "none")
  -u, --proxy-url string    The url where the proxy will redirect to
  -s, --secure              Run mock server using TLS (https)
  -v, --version             Version of Killgrave
  -w, --watcher             File watcher will reload the server on each file change

Using Killgrave by config file

If we want a more permanent configuration, we could use the option -config to specify the location of a configuration file.

The config file must be a YAML file with the following structure.

#config.yml

imposters_path: "imposters"
port: 3000
host: "localhost"
proxy:
  url: https://example.com
  mode: missing
watcher: true
cors:
  methods: ["GET"]
  headers: ["Content-Type"]
  exposed_headers: ["Cache-Control"]
  origins: ["*"]
  allow_credentials: true
watcher: true
secure: true

As you can see, you can configure all the options in a very easy way. For the above example, the file tree looks as follows, with the current working directory being mymock.

mymock/
    imposters/
        config.yml
        swapi_people.imp.json
        swapi_planets.imp.json
    Dockerfile
    MakeFile

Then in your config file, you will need to set the -imposters flag to . because the imposters folder is located in the same folder.

Historically, the options imposters_path, port, host were mandatory when using a configuration file. However, since the last version, they are no longer needed, so you can simply override those options if you want to. Furthermore, in previous versions, the imposters_path option refered to the path where the app was launched, but in the last version this is relative to the location of the config file.

The option cors is still optional and its options can be an empty array. If you want more information about the CORS options, visit the CORS section.

The watcher configuration field is optional. With this setting you can enable hot-reloads on imposter changes. Disabled by default.

The secure configuration field is optional. With this setting you can run your server using TLS options with a dummy certificate, so as to make it work with the HTTPS protocol. Disabled by default.

The option proxy-mode allows you to configure the mock in proxy mode. When this mode is enabled, Killgrave will forward any unconfigured requests to another server. More information: Proxy Section

How to use

Configure CORS

If you want to use killgrave from a client application you should consider configuring CORS.

In the CORS section of the file you can find the following options:

  • methods (string array)

    Represents the Access-Control-Request-Method header, if you don't specify it or if you leave it as an empty array, the default values will be:

    "GET", "HEAD", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "TRACE", "CONNECT"

  • headers (string array)

    Represents the Access-Control-Request-Headers header, if you don't specify it or if you leave it as an empty array, the default values will be:

    "X-Requested-With", "Content-Type", "Authorization"

  • exposed_headers (string array)

    Represents the Access-Control-Expose-Headers header, if you don't specify it or if you leave it as an empty array, the default values will be:

    "Cache-Control", "Content-Language", "Content-Type", "Expires", "Last-Modified", "Pragma"

  • origins (string array)

    Represents the Access-Control-Allow-Origin header, if you don't specify it or if you leave it as an empty array this option has not default value

  • allow_credentials (boolean)

    Enables or disables the Access-Control-Allow-Credentials header.

Preparing Killgrave for Proxy Mode

You can use Killgrave in proxy mode using the flags proxy-mode and proxy-url or their equivalent fields in the configuration file. The following three proxy modes are available:

  • none: Default. Killgrave will not behave as a proxy and the mock server will only use the configured imposters.
  • missing: With this mode the mock server will try to match the request with a configured imposter, but if no matching endpoint was found, the mock server will call to the real server, declared in the proxy-url configuration variable.
  • all: The mock server will always call to the real server, declared in the proxy-url configuration variable.

The proxy-url must be the root path of the proxied server. For example, if we have an API running on http://example.com/things, the proxy-url will be http://example.com.

Creating an Imposter

At least one imposter must be configured in order to run Killgrave. Files with the .imp.json extension in the imposters folder (default "imposters") will be interpreted as imposter files.

We use a rule-based system to match requests to imposters. Therefore, you have to organize your imposters from most restrictive to least. Here's an example of an imposter.

[
    {
        "request": {
            "method": "GET",
            "endpoint": "/gophers/01D8EMQ185CA8PRGE20DKZTGSR"            
        },
        "response": {
            "status": 200,
            "headers": {
                "Content-Type": "application/json"
            },
            "body": "{\"data\":{\"type\":\"gophers\",\"id\":\"01D8EMQ185CA8PRGE20DKZTGSR\",\"attributes\":{\"name\":\"Zebediah\",\"color\":\"Purples\",\"age\":55}}}"
        }
    }
]

This a very simple example. Killgrave has more possibilities for configuring imposters. Let's take a look at some of them in the next sections.

:warning: Remember that you will need to escape any special char, in the properties that admit text.

Imposters Structure

The imposter object can be divided in two parts:

Request

This part defines how Killgrave should determine whether an incoming request matches the imposter or not. The request object has the following properties:

  • method (mandatory): The HTTP method of the incoming request.
  • endpoint (mandatory): Path of the endpoint relative to the base. Supports regex.
  • schemaFile: A JSON schema to validate the incoming request against.
  • params: Restrict incoming requests by query parameters. More info can be found here. Supports regex.
  • headers: Restrict incoming requests by HTTP header. More info can be found here.
Response

This part defines how Killgrave should respond to the incoming request. The response object has the following properties:

  • status (mandatory): Integer defining the HTTP status to return.
  • body or bodyFile: The response body. Either a literal string (body) or a path to a file (bodyFile). bodyFile is especially useful in the case of large outputs. This property is optional: if not response body should be returned it should be removed or left empty.
  • headers: Headers to return in the response.
  • delay: Time the server waits before responding. This can help simulate network issues, or high server load. Uses the Go ParseDuration format. Also, you can specify minimum and maximum delays separated by ':'. The response delay will be chosen at random between these values. Default value is "0s" (no delay).

Using regex in imposters

Regex in the endpoint

Killgrave uses the gorilla/mux regex format for endpoint regex matching.

In the next example, we have configured an endpoint to match with any kind of ULID ID:

[
  {
    "request": {
      "method": "GET",
      "endpoint": "/gophers/{_id:[\\w]{26}}"
    },
    "response": {
      "status": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "body": "{\"data\":{\"type\":\"gophers\",\"id\":\"01D8EMQ185CA8PRGE20DKZTGSR\",\"attributes\":{\"name\":\"Zebediah\",\"color\":\"Purples\",\"age\":55}}}"
    }
  }
]
Regex in the query parameters:

Killgrave uses the gorilla/mux regex format for query parameter regex matching.

In this example, we have configured an imposter that only matches if we receive an apiKey as query parameter:

[
  {
    "request": {
      "method": "GET",
      "endpoint": "/gophers/{_id:[\\w]{26}}",
      "params": {
        "apiKey": "{_apiKey:[\\w]+}"
      }
    },
    "response": {
      "status": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "body": "{\"data\":{\"type\":\"gophers\",\"id\":\"01D8EMQ185CA8PRGE20DKZTGSR\",\"attributes\":{\"name\":\"Zebediah\",\"color\":\"Purples\",\"age\":55}}}"
    }
  }
]
Regex in the headers:

In this case we will not need the gorilla mux nomenclature to write our regex.

In the next example, we have configured an imposter that uses regex to match an Authorization header.

[
  {
    "request": {
      "method": "GET",
      "endpoint": "/gophers/{id:[\\w]{26}}",
      "headers": {
        "Authorization": "\\w+"
      }
    },
    "response": {
      "status": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "body": "{\"data\":{\"type\":\"gophers\",\"id\":\"01D8EMQ185CA8PRGE20DKZTGSR\",\"attributes\":{\"name\":\"Zebediah\",\"color\":\"Purples\",\"age\":55}}}"
    }
  }
]

Creating an imposter using JSON Schema

Sometimes, we need to validate our request more thoroughly. In cases like this we can create an imposter that only matches with a valid json schema.

To do that we will need to define our json schema first:

imposters/schemas/create_gopher_request.json

{
    "type": "object",
    "properties": {
        "data": {
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "gophers"
                    ]
                },
                "attributes": {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string"
                        },
                        "color": {
                            "type": "string"
                        },
                        "age": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "name",
                        "color",
                        "age"
                    ]
                }
            },
            "required": [
                "type",
                "attributes"
            ]
        }
    },
    "required": [
        "data"
    ]
}

With this json schema, we expect a request like this:

{
    "data": {
        "type": "gophers",
        "attributes": {
            "name": "Zebediah",
            "color": "Purples",
            "age": 55
        }
    }
}

Then our imposter will be configured as follows:

[
  {
    "request": {
        "method": "POST",
        "endpoint": "/gophers",
        "schemaFile": "schemas/create_gopher_request.json",
        "headers": {
            "Content-Type": "application/json"
        }
    },
    "response": {
        "status": 201,
        "headers": {
            "Content-Type": "application/json"
        }
    }
  }
]

The path where the schema is located is relative to where the imposters are.

Creating an imposter with delay

If we want to simulate a problem with the network, or create a more realistic response, we can use the delay property.

The delay property can take duration in the Go ParseDuration format. The server response will be delayed by the specified duration.

Alternatively, the delay property can take a range of two durations, separated by a ':'. In this case, the server will respond with a random delay in this range.

For example, we can modify our previous POST call to add a delay to determine that we want our response to be delayed by 1 to 5 seconds:

[
  {
    "request": {
        "method": "POST",
        "endpoint": "/gophers",
        "schemaFile": "schemas/create_gopher_request.json",
        "headers": {
            "Content-Type": "application/json"
        }
    },
    "response": {
        "status": 201,
        "headers": {
            "Content-Type": "application/json"
        },
        "delay": "1s:5s"
    }
  }
]

Creating an imposter with dynamic responses

Killgrave allows dynamic responses. Using this feature, Killgrave can return different responses on the same endpoint.

To do this, all imposters need to be ordered from most restrictive to least. Killgrave tries to match the request with each of the imposters in sequence, stopping at the first imposter that matches the request.

In the following example, we have defined multiple imposters for the POST /gophers endpoint. Let's say an incoming request does not match the JSON schema specified in the first imposter's schemaFile. Therefore, Killgrave skips this imposter and tries to match the request against the second imposter. This imposter is much less restrictive, so the request matches and the associated response is returned.

[
  {
    "request": {
        "method": "POST",
        "endpoint": "/gophers",
        "schemaFile": "schemas/create_gopher_request.json",
        "headers": {
            "Content-Type": "application/json"
        }
    },
    "response": {
        "status": 201,
        "headers": {
            "Content-Type": "application/json"
        }
    }
  },
  {
      "request": {
          "method": "POST",
          "endpoint": "/gophers"
      },
      "response": {
          "status": 400,
          "headers": {
              "Content-Type": "application/json"
          },
          "body": "{\"errors\":\"bad request\"}"
      }
  }
]

Contributing

Contributions are more than welcome, if you are interested please follow our guidelines to help you get started.

License

MIT License, see LICENSE

Frequently asked questions

Is killgrave free to use?

killgrave is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does killgrave do?

Simple way to generate mock servers written in Go

What is killgrave written in?

killgrave is primarily written in Go. Its source is publicly available at https://github.com/friendsofgo/killgrave, and it has 563 GitHub stars.