{"id":20611873,"url":"https://github.com/akupila/recorder","last_synced_at":"2025-04-15T05:42:40.792Z","repository":{"id":49545563,"uuid":"184225155","full_name":"akupila/recorder","owner":"akupila","description":"HTTP traffic record \u0026 replay for go","archived":false,"fork":false,"pushed_at":"2021-06-15T07:22:34.000Z","size":27,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T05:42:38.331Z","etag":null,"topics":["debugging","go","http","recorder","testing"],"latest_commit_sha":null,"homepage":null,"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/akupila.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-30T08:41:13.000Z","updated_at":"2024-04-06T19:57:37.000Z","dependencies_parsed_at":"2022-08-19T03:20:15.712Z","dependency_job_id":null,"html_url":"https://github.com/akupila/recorder","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akupila%2Frecorder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akupila%2Frecorder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akupila%2Frecorder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akupila%2Frecorder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akupila","download_url":"https://codeload.github.com/akupila/recorder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249016306,"owners_count":21198828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["debugging","go","http","recorder","testing"],"created_at":"2024-11-16T10:22:26.484Z","updated_at":"2025-04-15T05:42:40.757Z","avatar_url":"https://github.com/akupila.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# recorder\n\n[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](https://godoc.org/github.com/akupila/recorder)\n[![CircleCI](https://circleci.com/gh/akupila/recorder.svg?style=svg)](https://circleci.com/gh/akupila/recorder)\n[![goreportcard](https://goreportcard.com/badge/github.com/akupila/recorder)](https://goreportcard.com/report/github.com/akupila/recorder)\n\n\u003c!-- TOC GFM --\u003e\n\n- [Overview](#overview)\n  - [Example usage](#example-usage)\n  - [Modes](#modes)\n  - [Filters](#filters)\n    - [Remove header from request](#remove-header-from-request)\n    - [Remove header from response](#remove-header-from-response)\n    - [Custom](#custom)\n  - [Prior art](#prior-art)\n  - [License](#license)\n\n\u003c!-- /TOC --\u003e\n\n# Overview\n\nThe recorder is a small helper package, primarily intended to help with unit\ntests. It is capable of recording and replaying traffic, avoiding real network\nrequests.\n\nIn the default mode, responses are read from disk, allowing the network\nroundtrip to be avoided. This can be useful for a couple reasons:\n\n- Faster\n- Works offline\n- Reduces side-effects on called APIs (such as when testing cloud service\n  provider endpoints)\n\nIn addition, with the `Passthrough` mode, requests can be recorded an asserted\nin unit tests.\n\nUnless the mode is set to `Passthrough`, the request-response is recorded in a\n`yml` on disk, such as:\n\n```yaml\n# request 0\n# timestamp 2019-04-30 10:02:04 +0000 UTC\n# roundtrip 398ms\nrequest:\n  method: POST\n  url: https://jsonplaceholder.typicode.com/posts\n  headers:\n    Content-Type: application/json\nresponse:\n  status_code: 201\n  headers:\n    Cache-Control: no-cache\n    Content-Length: '69'\n    Content-Type: application/json; charset=utf-8\n    Date: Tue, 30 Apr 2019 10:02:04 GMT\n    Location: http://jsonplaceholder.typicode.com/posts/101\n    Pragma: no-cache\n  body: |-\n    {\n      \"title\": \"hello\",\n      \"body\": \"world\",\n      \"userId\": 1,\n      \"id\": 101\n    }\n```\n\n## Example usage\n\n```go\n// Create a new recorder.\n// Data will be saved in testdata/example.yml\nrec := recorder.New(\"testdata/example\")\n\n// Create HTTP client with recorder transport\ncli := \u0026http.Client{\n    Transport: rec,\n}\n\n// Perform a request\nresp, err := cli.Get(\"https://jsonplaceholder.typicode.com/posts/1\")\nif err != nil {\n    log.Fatal(err)\n}\n\n// Response is only done if required\nb, err := httputil.DumpResponse(resp, true)\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(string(b))\n```\n\n## Modes\n\nModes allow granular control of behavior.\n\n| Mode          | Behavior                                                                 |\n| ------------- | ------------------------------------------------------------------------ |\n| `Auto`        | Perform network requests if no stored file exists                        |\n| `ReplayOnly`  | Do not allow network traffic, only return stored files                   |\n| `Record`      | Always perform request and overwrite existing files                      |\n| `Passthrough` | No files are saved on disk but requests can be retrieved with `Lookup()` |\n\nIf no mode is set, `Auto` is used.\n\nThe `Passthrough` mode disabled loading and saving files but can be useful for\nasserting if the expected requests were made in tests.\n\n## Filters\n\nFilters allow removing sensitive data from the saved files.\n\nThe filters are executed **after** the request but **before** saving files to disk.\n\n### Remove header from request\n\nThis will remove the `Authorization` header from the request:\n\n```go\nrec := recorder.New(\"testdata/private-api\", recorder.RemoveRequestHeader(\"Authorization\"))\n\ncli := \u0026http.Client{\n    Transport: rec,\n}\n\nreq, _ := http.NewRequest(\"https://example.com\", \"application/json\", strings.NewReader(\"{}\"))\nreq.Header.Add(\"Authorization\", \"abcdef\")\n\n_, err := cli.Do(req)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Authorization header is not saved to disk\n```\n\n### Remove header from response\n\nThis will remove the `Set-Cookie` header from the response:\n\n```go\nrec := recorder.New(\"testdata/private-api\", recorder.RemoveResponseHeader(\"Set-Cookie\"))\n\ncli := \u0026http.Client{\n    Transport: rec,\n}\n\n_, err := cli.Get(\"https://example.com\")\nif err != nil {\n    log.Fatal(err)\n}\n\n// The saved file will not contain the Set-Cookie header that was set by the server.\n```\n\n### Custom\n\nIn addition to the built in filters, custom filters can be implemented by\npassing functions with a signature `func (entry *recorder.Entry) {}`.\n\n```go\nrec := recorder.New(\"testdata/request-header\", func(e *recorder.Entry) {\n    // Modify e.Request and e.Response\n})\n\ncli := \u0026http.Client{\n    Transport: rec,\n}\n\n_, err := cli.Get(\"https://example.com\")\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n## Prior art\n\nThis library is inspired by:\n\n- https://github.com/dnaeon/go-vcr\n- https://github.com/ad2games/vcr-go\n- https://github.com/nock/nock#recording\n\nThe reason for writing this library is primarily flexiblity in setting the mode\nand different API (no VCR references).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakupila%2Frecorder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakupila%2Frecorder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakupila%2Frecorder/lists"}