{"id":19806360,"url":"https://github.com/ory/herodot","last_synced_at":"2025-04-12T16:35:22.857Z","repository":{"id":41211631,"uuid":"74656290","full_name":"ory/herodot","owner":"ory","description":"A lightweight Go library for writing responses and errors to HTTP","archived":false,"fork":false,"pushed_at":"2025-03-18T10:46:52.000Z","size":461,"stargazers_count":118,"open_issues_count":3,"forks_count":17,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-12T00:28:59.582Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ory.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"_ory","open_collective":"ory"}},"created_at":"2016-11-24T09:08:43.000Z","updated_at":"2025-04-04T04:32:40.000Z","dependencies_parsed_at":"2024-04-12T10:24:58.578Z","dependency_job_id":"29b243f5-7240-41d4-9a86-ee1e1278f819","html_url":"https://github.com/ory/herodot","commit_stats":{"total_commits":161,"total_committers":15,"mean_commits":"10.733333333333333","dds":"0.40993788819875776","last_synced_commit":"4fc906c59bee2164dc1d9cb4490eaa0d99a11e75"},"previous_names":["ory-am/herodot"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ory%2Fherodot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ory%2Fherodot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ory%2Fherodot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ory%2Fherodot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ory","download_url":"https://codeload.github.com/ory/herodot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248597122,"owners_count":21130813,"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":[],"created_at":"2024-11-12T09:07:22.471Z","updated_at":"2025-04-12T16:35:22.831Z","avatar_url":"https://github.com/ory.png","language":"Go","funding_links":["https://patreon.com/_ory","https://opencollective.com/ory"],"categories":[],"sub_categories":[],"readme":"# herodot\n\n[![Join the chat at https://slack.ory.sh/](https://img.shields.io/badge/join-chat-00cc99.svg)](https://slack.ory.sh/)\n[![Build Status](https://travis-ci.org/ory/herodot.svg?branch=master)](https://travis-ci.org/ory/herodot)\n[![Coverage Status](https://coveralls.io/repos/github/ory/herodot/badge.svg?branch=master)](https://coveralls.io/github/ory/herodot?branch=master)\n\n---\n\nHerodot is a lightweight SDK for writing RESTful responses. It is comparable to\n[render](https://github.com/unrolled/render) but provides easier error handling.\nThe error model implements the well established\n[Google API Design Guide](https://cloud.google.com/apis/design/errors). Herodot\ncurrently supports only JSON responses but can be extended easily.\n\nHerodot is used by [ORY Hydra](https://github.com/ory/hydra) and serves millions\nof requests already.\n\n## Installation\n\nHerodot is versioned using\n[go modules](https://blog.golang.org/using-go-modules) and works best with\n[pkg/errors](https://github.com/pkg/errors). To install it, run\n\n```\ngo get -u github.com/ory/herodot\n```\n\n## Upgrading\n\nTips on upgrading can be found in [UPGRADE.md](UPGRADE.md)\n\n## Usage\n\nUsing Herodot is straightforward. The examples below will help you get started.\n\n### JSON\n\nHerodot supplies an interface, allowing to return errors in many data formats\nlike XML and others. Currently, it supports only JSON.\n\n#### Write responses\n\n```go\nvar hd = herodot.NewJSONWriter(nil)\n\nfunc GetHandler(rw http.ResponseWriter, r *http.Request) {\n\t// run your business logic here\n\thd.Write(rw, r, map[string]interface{}{\n\t    \"key\": \"value\"\n\t})\n}\n\ntype MyStruct struct {\n\tKey string `json:\"key\"`\n}\n\nfunc GetHandlerWithStruct(rw http.ResponseWriter, r *http.Request) {\n\t// business logic\n\thd.Write(rw, r, \u0026MyStruct{Key: \"value\"})\n}\n\nfunc PostHandlerWithStruct(rw http.ResponseWriter, r *http.Request) {\n\t// business logic\n\thd.WriteCreated(rw, r, \"/path/to/the/resource/that/was/created\", \u0026MyStruct{Key: \"value\"})\n}\n\nfunc SomeHandlerWithArbitraryStatusCode(rw http.ResponseWriter, r *http.Request) {\n\t// business logic\n\thd.WriteCode(rw, r, http.StatusAccepted, \u0026MyStruct{Key: \"value\"})\n}\n\nfunc SomeHandlerWithArbitraryStatusCode(rw http.ResponseWriter, r *http.Request) {\n\t// business logic\n\thd.WriteCode(rw, r, http.StatusAccepted, \u0026MyStruct{Key: \"value\"})\n}\n```\n\n#### Dealing with errors\n\n```go\nvar writer = herodot.NewJSONWriter(nil)\n\nfunc GetHandlerWithError(rw http.ResponseWriter, r *http.Request) {\n    if err := someFunctionThatReturnsAnError(); err != nil {\n        hd.WriteError(w, r, err)\n        return\n    }\n\n    // ...\n}\n\nfunc GetHandlerWithErrorCode(rw http.ResponseWriter, r *http.Request) {\n    if err := someFunctionThatReturnsAnError(); err != nil {\n        hd.WriteErrorCode(w, r, http.StatusBadRequest, err)\n        return\n    }\n\n    // ...\n}\n```\n\n### Errors\n\nHerodot implements the error model of the well established\n[Google API Design Guide](https://cloud.google.com/apis/design/errors).\nAdditionally, it makes the fields `request` and `reason` available. A complete\nHerodot error response looks like this:\n\n```json\n{\n  \"error\": {\n    \"code\": 404,\n    \"status\": \"some-status\",\n    \"request\": \"foo\",\n    \"reason\": \"some-reason\",\n    \"details\": [{ \"foo\": \"bar\" }],\n    \"message\": \"foo\"\n  }\n}\n```\n\nTo add context to your errors, implement `herodot.ErrorContextCarrier`. If you\nonly want to set the status code of errors implement\n[herodot.StatusCodeCarrier](https://github.com/ory/herodot/blob/master/error.go#L22-L26).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fory%2Fherodot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fory%2Fherodot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fory%2Fherodot/lists"}