{"id":13504633,"url":"https://github.com/friendsofgo/killgrave","last_synced_at":"2026-02-05T11:33:05.747Z","repository":{"id":37735217,"uuid":"181223659","full_name":"friendsofgo/killgrave","owner":"friendsofgo","description":"Simple way to generate mock servers written in Go","archived":false,"fork":false,"pushed_at":"2025-02-17T04:54:07.000Z","size":1039,"stargazers_count":553,"open_issues_count":33,"forks_count":103,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-08-14T09:26:10.578Z","etag":null,"topics":["go","golang","golang-application","hacktoberfest","http","imposter","mock","mock-server","proxy-server"],"latest_commit_sha":null,"homepage":"https://friendsofgo.github.io/killgrave/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/friendsofgo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-13T20:12:02.000Z","updated_at":"2025-08-08T11:50:27.000Z","dependencies_parsed_at":"2024-08-12T09:28:24.035Z","dependency_job_id":"d52df98a-d0ae-4cb6-bfbd-fbbba844dcb1","html_url":"https://github.com/friendsofgo/killgrave","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/friendsofgo/killgrave","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendsofgo%2Fkillgrave","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendsofgo%2Fkillgrave/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendsofgo%2Fkillgrave/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendsofgo%2Fkillgrave/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/friendsofgo","download_url":"https://codeload.github.com/friendsofgo/killgrave/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendsofgo%2Fkillgrave/sbom","scorecard":{"id":411583,"data":{"date":"2025-08-11","repo":{"name":"github.com/friendsofgo/killgrave","commit":"2424d0a3c275d4b41a323bdaba2b0656100de975"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":2,"reason":"Found 6/22 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yaml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/friendsofgo/killgrave/release.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Info:   0 out of   5 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.5.1 not signed: https://api.github.com/repos/friendsofgo/killgrave/releases/130044241","Warn: release artifact v0.5.0 not signed: https://api.github.com/repos/friendsofgo/killgrave/releases/102742658","Warn: release artifact v0.4.1 not signed: https://api.github.com/repos/friendsofgo/killgrave/releases/41941876","Warn: release artifact v0.4.0 not signed: https://api.github.com/repos/friendsofgo/killgrave/releases/23267115","Warn: release artifact v0.3.3 not signed: https://api.github.com/repos/friendsofgo/killgrave/releases/17294491","Warn: release artifact v0.5.1 does not have provenance: https://api.github.com/repos/friendsofgo/killgrave/releases/130044241","Warn: release artifact v0.5.0 does not have provenance: https://api.github.com/repos/friendsofgo/killgrave/releases/102742658","Warn: release artifact v0.4.1 does not have provenance: https://api.github.com/repos/friendsofgo/killgrave/releases/41941876","Warn: release artifact v0.4.0 does not have provenance: https://api.github.com/repos/friendsofgo/killgrave/releases/23267115","Warn: release artifact v0.3.3 does not have provenance: https://api.github.com/repos/friendsofgo/killgrave/releases/17294491"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":2,"reason":"SAST tool is not run on all commits -- score normalized to 2","details":["Warn: 4 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T22:49:57.402Z","repository_id":37735217,"created_at":"2025-08-18T22:49:57.402Z","updated_at":"2025-08-18T22:49:57.402Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29120642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T10:47:47.471Z","status":"ssl_error","status_checked_at":"2026-02-05T10:45:08.119Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-application","hacktoberfest","http","imposter","mock","mock-server","proxy-server"],"created_at":"2024-08-01T00:00:48.420Z","updated_at":"2026-02-05T11:33:05.730Z","avatar_url":"https://github.com/friendsofgo.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://res.cloudinary.com/fogo/image/upload/c_scale,w_350/v1555701634/fogo/projects/gopher-killgrave.png\" alt=\"Golang Killgrave\"/\u003e\n\u003c/p\u003e\n\n# Killgrave\n\nKillgrave is a simulator for HTTP-based APIs, in simple words a **Mock Server**, very easy to use, made in **Go**.\n\n![Github actions](https://github.com/friendsofgo/killgrave/actions/workflows/main.yaml/badge.svg?branch=main)\n[![Version](https://img.shields.io/github/release/friendsofgo/killgrave.svg?style=flat-square)](https://github.com/friendsofgo/killgrave/releases/latest)\n[![Go Report Card](https://goreportcard.com/badge/github.com/friendsofgo/killgrave)](https://goreportcard.com/report/github.com/friendsofgo/killgrave)\n[![FriendsOfGo](https://img.shields.io/badge/powered%20by-Friends%20of%20Go-73D7E2.svg)](https://friendsofgo.tech)\n\n# Table of Content\n- [Overview](#overview)\n- [Concepts](#concepts)\n    * [Imposters](#imposters)\n- [Installing](#installing)\n    * [Homebrew](#homebrew)\n    * [Docker](#docker)\n    * [Compile by yourself](#compile-by-yourself)\n    * [Other](#other)\n- [Getting Started](#getting-started)\n    * [Using Killgrave by command line](#using-killgrave-from-the-command-line)\n    * [Using Killgrave by config file](#using-killgrave-by-config-file)\n    * [Configure CORS](#configure-cors)\n    * [Preparing Killgrave for Proxy Mode](#preparing-killgrave-for-proxy-mode)\n    * [Creating an Imposter](#creating-an-imposter)\n    * [Imposters structure](#imposters-structure)\n    * [Using regex in imposters](#using-regex-in-imposters)\n    * [Creating an imposter using JSON Schema](#creating-an-imposter-using-json-schema)\n    * [Creating an imposter with delay](#creating-an-imposter-with-delay)\n    * [Creating an imposter with dynamic responses](#creating-an-imposter-with-dynamic-responses)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Overview\n\n**Killgrave** is a tool that provides a simple way to create a powerful simulator for HTTP-based APIs.\n\nThe Killgrave's philosophy is to provide an easy way to configure your *mock server*, ensuring that you don't need to learn\nanother tooling language. For that reason we use `json` and `yaml` to generate all necessary configurations.\n\nKillgrave provides:\n\n* An easy way to create imposters files, using `json`\n* The possibility to validate requests against [json schemas](https://json-schema.org/).\n* Validation of request headers.\n* Using regex to allow different parameters in headers and urls.\n* Custom body and dynamic body responses.\n* Using all content-types bodies, (`application/json`, `text/html`, `text/plain`, `image/jpeg`, etc. )\n* Configure response headers.\n* Configure CORS.\n* Simulate network issues and server high loads with imposter responses delay.\n* Using configurable proxy server to call to the original server.\n* Run the tool using flags or using a config file.\n* Run your mock server using a watcher to reload on configuration changes.\n\n## Concepts\n\n### Imposters\n\nImposters are the most important concept of the Killgrave tool. They define the rules that determine how the server should respond to a request.\n\nYou can identify a Killgrave imposter file by its extension: `.imp.json`.\n\nYou can learn more about how to configure imposters in the [Imposter Configuration Section](#imposters).\n\n## Installing\n\u003e :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`](https://semver.org/) as usual.\n\nYou can install Killgrave in different ways, but all of them are very simple:\n\n### Homebrew \n\nIf you are a Mac user, you can install Killgrave using [Homebrew](https://brew.sh/):\n\n```sh\n$ brew install friendsofgo/tap/killgrave\n```\n\n:warning:  If you are installing via Homebrew, you always get the [latest Killgrave version](https://github.com/friendsofgo/killgrave/releases), we hope to fix this soon.\n\n### Docker\n\nThe application is also available through [Docker](https://hub.docker.com/r/friendsofgo/killgrave).\n\n```bash\ndocker run -it --rm -p 3000:3000 -v $PWD/:/home -w /home friendsofgo/killgrave --host 0.0.0.0\n```\n\n`-p 3000:3000` [publishes](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) port 3000 (Killgrave's default port) inside the\ncontainer to port 3000 on the host machine.\n\n`--host 0.0.0.0` is necessary to allow Killgrave to listen and respond to requests from outside the container (the default,\n`localhost`, will not capture requests from the host network).\n\n### Compile by yourself\n\nIf you want to use `Killgrave` from the source code, first you will need to clone the repository:\n\n```sh\ngit clone git@github.com:friendsofgo/killgrave.git\n```\n\nSelect the branch you want to use (`main` by default), and then compile `Killgrave`:\n\n```sh\nmake build\n```\n\nThis command will create an executable into the path `bin/killgrave`. We highly recommended the usage of this command\nto compile the software because parameters such as `version` are added to the compilation, which are necessary when reporting a bug.\n\n### Other\n\nWindows and Linux users can download binaries from the [Github Releases](https://github.com/friendsofgo/killgrave/releases) page.\n\n## Getting Started\n\nTo start Killgrave, you simply run the following.\n\n```sh\n$ killgrave\n```\n\nWhile you are welcome to provide your own configuration, Killgrave will default to the following configuration:\n\n* **imposters path**: `imposters`\n* **host**: `localhost`\n* **port**: `3000`\n* **CORS**: `[]`\n* **proxy**: `none`\n* **watcher**: `false`\n\n### Using Killgrave from the command line\n\nKillgrave 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](#using-killgrave-by-config-file).\n\n```sh\n$ killgrave -h\n\nSimple way to generate mock servers\n\nUsage:\n  killgrave [flags]\n\nFlags:\n  -c, --config string       Path to your configuration file\n  -h, --help                Help for Killgrave\n  -H, --host string         Set a different host than localhost (default \"localhost\")\n  -i, --imposters string    Directory where your imposters are located (default \"imposters\")\n  -P, --port int            Port to run the server (default 3000)\n  -m, --proxy-mode string   Proxy mode, the options are all, missing or none (default \"none\")\n  -u, --proxy-url string    The url where the proxy will redirect to\n  -s, --secure              Run mock server using TLS (https)\n  -v, --version             Version of Killgrave\n  -w, --watcher             File watcher will reload the server on each file change\n```\n\n### Using Killgrave by config file\n\nIf we want a more permanent configuration, we could use the option `-config` to specify the location of a configuration file.\n\nThe config file must be a YAML file with the following structure.\n\n```yaml\n#config.yml\n\nimposters_path: \"imposters\"\nport: 3000\nhost: \"localhost\"\nproxy:\n  url: https://example.com\n  mode: missing\nwatcher: true\ncors:\n  methods: [\"GET\"]\n  headers: [\"Content-Type\"]\n  exposed_headers: [\"Cache-Control\"]\n  origins: [\"*\"]\n  allow_credentials: true\nwatcher: true\nsecure: true\n```\n\nAs 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`.\n\n```\nmymock/\n    imposters/\n        config.yml\n        swapi_people.imp.json\n        swapi_planets.imp.json\n    Dockerfile\n    MakeFile\n```\n\nThen in your config file, you will need to set the `-imposters` flag to `.` because the imposters folder is located in the same folder.\n\nHistorically, 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.\nFurthermore, 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.\n\nThe option `cors` is still optional and its options can be an empty array.\nIf you want more information about the CORS options, visit the [CORS section](#configure-cors).\n\nThe `watcher` configuration field is optional. With this setting you can enable hot-reloads on imposter changes. Disabled by default.\n\nThe `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.\n\nThe 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](#prepare-killgrave-for-proxy-mode)\n\n## How to use\n\n### Configure CORS\n\nIf you want to use `killgrave` from a client application you should consider configuring CORS.\n\nIn the CORS section of the file you can find the following options:\n\n- **methods** (string array)\n  \n  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:\n\n  `\"GET\", \"HEAD\", \"POST\", \"PUT\", \"OPTIONS\", \"DELETE\", \"PATCH\", \"TRACE\", \"CONNECT\"`\n\n- **headers** (string array)\n  \n  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:\n\n  `\"X-Requested-With\", \"Content-Type\", \"Authorization\"`\n\n- **exposed_headers** (string array)\n  \n  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:\n\n  `\"Cache-Control\", \"Content-Language\", \"Content-Type\", \"Expires\", \"Last-Modified\", \"Pragma\"`\n\n- **origins** (string array)\n  \n  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\n\n- **allow_credentials** (boolean)\n  \n  Enables or disables the **Access-Control-Allow-Credentials header**.\n\n### Preparing Killgrave for Proxy Mode\n\nYou 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:\n* `none`: Default. Killgrave will not behave as a proxy and the mock server will only use the configured imposters.\n* `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.\n* `all`: The mock server will always call to the real server, declared in the `proxy-url` configuration variable.\n\nThe `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`.\n\n### Creating an Imposter\n\nAt 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.\n\nWe 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.\n\n```json\n[\n    {\n        \"request\": {\n            \"method\": \"GET\",\n            \"endpoint\": \"/gophers/01D8EMQ185CA8PRGE20DKZTGSR\"            \n        },\n        \"response\": {\n            \"status\": 200,\n            \"headers\": {\n                \"Content-Type\": \"application/json\"\n            },\n            \"body\": \"{\\\"data\\\":{\\\"type\\\":\\\"gophers\\\",\\\"id\\\":\\\"01D8EMQ185CA8PRGE20DKZTGSR\\\",\\\"attributes\\\":{\\\"name\\\":\\\"Zebediah\\\",\\\"color\\\":\\\"Purples\\\",\\\"age\\\":55}}}\"\n        }\n    }\n]\n```\n\nThis a very simple example. Killgrave has more possibilities for configuring imposters. Let's take a look at some of them in the next sections.\n\n:warning:  Remember that you will need to escape any special char, in the properties that admit text.\n\n### Imposters Structure\n\nThe imposter object can be divided in two parts:\n\n* [Request](#request)\n* [Response](#response)\n\n#### Request\n\nThis part defines how Killgrave should determine whether an incoming request matches the imposter or not. The `request` object has the following properties:\n\n* `method` (\u003cspan style=\"color:red\"\u003emandatory\u003c/span\u003e): The [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) of the incoming request.\n* `endpoint` (\u003cspan style=\"color:red\"\u003emandatory\u003c/span\u003e): Path of the endpoint relative to the base. Supports regex.\n* `schemaFile`: A JSON schema to validate the incoming request against.\n* `params`: Restrict incoming requests by query parameters. More info can be found [here](#create-an-imposter-with-query-params). Supports regex.\n* `headers`: Restrict incoming requests by HTTP header. More info can be found [here](#create-an-imposter-with-headers).\n\n#### Response\n\nThis part defines how Killgrave should respond to the incoming request. The `response` object has the following properties:\n\n* `status` (\u003cspan style=\"color:red\"\u003emandatory\u003c/span\u003e): Integer defining the HTTP status to return.\n* `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.\nThis property is optional: if not response body should be returned it should be removed or left empty.\n* `headers`: Headers to return in the response.\n* `delay`: Time the server waits before responding. This can help simulate network issues, or high server load. Uses the [Go ParseDuration format](https://pkg.go.dev/time#ParseDuration). 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).\n\n### Using regex in imposters\n\n* [Using regex in the endpoint](#regex-on-the-endpoint)\n* [Using regex in the query parameters](#regex-on-the-params)\n* [Using regex in the headers](#regex-on-the-headers)\n\n#### Regex in the endpoint\n\nKillgrave uses the [gorilla/mux](https://github.com/gorilla/mux) regex format for endpoint regex matching.\n\nIn the next example, we have configured an endpoint to match with any kind of [ULID ID](https://cran.r-project.org/web/packages/ulid/vignettes/intro-to-ulid.html):\n\n```json\n[\n  {\n    \"request\": {\n      \"method\": \"GET\",\n      \"endpoint\": \"/gophers/{_id:[\\\\w]{26}}\"\n    },\n    \"response\": {\n      \"status\": 200,\n      \"headers\": {\n        \"Content-Type\": \"application/json\"\n      },\n      \"body\": \"{\\\"data\\\":{\\\"type\\\":\\\"gophers\\\",\\\"id\\\":\\\"01D8EMQ185CA8PRGE20DKZTGSR\\\",\\\"attributes\\\":{\\\"name\\\":\\\"Zebediah\\\",\\\"color\\\":\\\"Purples\\\",\\\"age\\\":55}}}\"\n    }\n  }\n]\n```\n\n#### Regex in the query parameters:\n\nKillgrave uses the [gorilla/mux](https://github.com/gorilla/mux) regex format for query parameter regex matching.\n\nIn this example, we have configured an imposter that only matches if we receive an apiKey as query parameter:\n\n```json\n[\n  {\n    \"request\": {\n      \"method\": \"GET\",\n      \"endpoint\": \"/gophers/{_id:[\\\\w]{26}}\",\n      \"params\": {\n        \"apiKey\": \"{_apiKey:[\\\\w]+}\"\n      }\n    },\n    \"response\": {\n      \"status\": 200,\n      \"headers\": {\n        \"Content-Type\": \"application/json\"\n      },\n      \"body\": \"{\\\"data\\\":{\\\"type\\\":\\\"gophers\\\",\\\"id\\\":\\\"01D8EMQ185CA8PRGE20DKZTGSR\\\",\\\"attributes\\\":{\\\"name\\\":\\\"Zebediah\\\",\\\"color\\\":\\\"Purples\\\",\\\"age\\\":55}}}\"\n    }\n  }\n]\n```\n\n#### Regex in the headers:\n\nIn this case we will not need the `gorilla mux nomenclature` to write our regex.\n\nIn the next example, we have configured an imposter that uses regex to match an Authorization header.\n\n```json\n[\n  {\n    \"request\": {\n      \"method\": \"GET\",\n      \"endpoint\": \"/gophers/{id:[\\\\w]{26}}\",\n      \"headers\": {\n        \"Authorization\": \"\\\\w+\"\n      }\n    },\n    \"response\": {\n      \"status\": 200,\n      \"headers\": {\n        \"Content-Type\": \"application/json\"\n      },\n      \"body\": \"{\\\"data\\\":{\\\"type\\\":\\\"gophers\\\",\\\"id\\\":\\\"01D8EMQ185CA8PRGE20DKZTGSR\\\",\\\"attributes\\\":{\\\"name\\\":\\\"Zebediah\\\",\\\"color\\\":\\\"Purples\\\",\\\"age\\\":55}}}\"\n    }\n  }\n]\n```\n\n### Creating an imposter using JSON Schema\n\nSometimes, we need to validate our request more thoroughly. In cases like this we can\ncreate an imposter that only matches with a valid [json schema](https://json-schema.org/).\n\nTo do that we will need to define our `json schema` first:\n\n`imposters/schemas/create_gopher_request.json`\n\n```json\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"data\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"type\": {\n                    \"type\": \"string\",\n                    \"enum\": [\n                        \"gophers\"\n                    ]\n                },\n                \"attributes\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"name\": {\n                            \"type\": \"string\"\n                        },\n                        \"color\": {\n                            \"type\": \"string\"\n                        },\n                        \"age\": {\n                            \"type\": \"integer\"\n                        }\n                    },\n                    \"required\": [\n                        \"name\",\n                        \"color\",\n                        \"age\"\n                    ]\n                }\n            },\n            \"required\": [\n                \"type\",\n                \"attributes\"\n            ]\n        }\n    },\n    \"required\": [\n        \"data\"\n    ]\n}\n```\n\nWith this `json schema`, we expect a `request` like this:\n\n```json\n{\n    \"data\": {\n        \"type\": \"gophers\",\n        \"attributes\": {\n            \"name\": \"Zebediah\",\n            \"color\": \"Purples\",\n            \"age\": 55\n        }\n    }\n}\n```\n\nThen our imposter will be configured as follows:\n\n````json\n[\n  {\n    \"request\": {\n        \"method\": \"POST\",\n        \"endpoint\": \"/gophers\",\n        \"schemaFile\": \"schemas/create_gopher_request.json\",\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        }\n    },\n    \"response\": {\n        \"status\": 201,\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        }\n    }\n  }\n]\n````\n\nThe path where the schema is located is relative to where the imposters are.\n\n### Creating an imposter with delay\n\nIf we want to simulate a problem with the network, or create a more realistic response, we can use the `delay` property.\n\nThe `delay` property can take duration in the [Go ParseDuration format](https://golang.org/pkg/time/#ParseDuration). The server response will be delayed by the specified duration.\n\nAlternatively, 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.\n\nFor 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:\n\n````json\n[\n  {\n    \"request\": {\n        \"method\": \"POST\",\n        \"endpoint\": \"/gophers\",\n        \"schemaFile\": \"schemas/create_gopher_request.json\",\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        }\n    },\n    \"response\": {\n        \"status\": 201,\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        },\n        \"delay\": \"1s:5s\"\n    }\n  }\n]\n````\n\n### Creating an imposter with dynamic responses\n\nKillgrave allows dynamic responses. Using this feature, Killgrave can return different responses on the same endpoint.\n\nTo 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.\n\nIn 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.\n\n````json\n[\n  {\n    \"request\": {\n        \"method\": \"POST\",\n        \"endpoint\": \"/gophers\",\n        \"schemaFile\": \"schemas/create_gopher_request.json\",\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        }\n    },\n    \"response\": {\n        \"status\": 201,\n        \"headers\": {\n            \"Content-Type\": \"application/json\"\n        }\n    }\n  },\n  {\n      \"request\": {\n          \"method\": \"POST\",\n          \"endpoint\": \"/gophers\"\n      },\n      \"response\": {\n          \"status\": 400,\n          \"headers\": {\n              \"Content-Type\": \"application/json\"\n          },\n          \"body\": \"{\\\"errors\\\":\\\"bad request\\\"}\"\n      }\n  }\n]\n````\n\n## Contributing\n[Contributions](CONTRIBUTING.md) are more than welcome, if you are interested please follow our guidelines to help you get started.\n\n## License\nMIT License, see [LICENSE](https://github.com/friendsofgo/killgrave/blob/main/LICENSE)\n","funding_links":[],"categories":["Go"],"sub_categories":["Misc"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffriendsofgo%2Fkillgrave","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffriendsofgo%2Fkillgrave","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffriendsofgo%2Fkillgrave/lists"}