{"id":37088549,"url":"https://github.com/ooaklee/reply","last_synced_at":"2026-01-14T10:52:43.279Z","repository":{"id":47144024,"uuid":"399739418","full_name":"ooaklee/reply","owner":"ooaklee","description":"💬 Go library to shape and standardise the responses sent by API services 💬","archived":false,"fork":false,"pushed_at":"2025-08-07T13:15:54.000Z","size":79,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-09T21:52:49.572Z","etag":null,"topics":["api","go","golang","http","json","json-api","response","response-management","rest"],"latest_commit_sha":null,"homepage":"","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/ooaklee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"zenodo":null}},"created_at":"2021-08-25T08:06:46.000Z","updated_at":"2025-08-03T08:50:09.000Z","dependencies_parsed_at":"2025-07-31T06:28:42.992Z","dependency_job_id":"2a18e978-d1ee-4759-a62b-1c86fa29af91","html_url":"https://github.com/ooaklee/reply","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/ooaklee/reply","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Freply","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Freply/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Freply/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Freply/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ooaklee","download_url":"https://codeload.github.com/ooaklee/reply/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Freply/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28417716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["api","go","golang","http","json","json-api","response","response-management","rest"],"created_at":"2026-01-14T10:52:42.568Z","updated_at":"2026-01-14T10:52:43.270Z","avatar_url":"https://github.com/ooaklee.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# reply\n\n`reply` is a Go library that supports developers with shaping and standardising the responses sent from their API service(s). It also allows users to predefine non-successful error objects, giving a granularity down to `title`, `description`, `status code`, and many more through the error manifest(s) passed to the `Replier`.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n  - [How to create a `Replier`](#how-to-create-a-replier)\n  - [More about the `ErrorManifest`](#more-about-the-errormanifest)\n    - [Deeper look into `ErrorManifestItem`](#deeper-look-into-errormanifestitem)\n- [How to send a response(s)](#how-to-send-a-responses)\n  - [Making use of error manifest](#making-use-of-error-manifest)\n  - [Sending  \"successful responses\"](#sending--successful-responses)\n- [Transfer Objects](#transfer-objects)\n  - [Base Transfer Object (`TransferObject`)](#base-transfer-object-transferobject)\n  - [Error Transfer Object (`TransferObjectError`)](#error-transfer-object-transferobjecterror)\n- [Response Types](#response-types)\n  - [Universal Attributes](#universal-attributes)\n  - [Error Response Type](#error-response-type)\n    - [As code (including aide example)](#as-code-including-aide-example)\n    - [JSON Representation](#json-representation)\n      - [With `Meta`](#with-meta)\n  - [Token Response Type](#token-response-type)\n    - [As code (including aide example)](#as-code-including-aide-example-1)\n    - [JSON Representation](#json-representation-1)\n      - [With `Meta`](#with-meta-1)\n  - [Data Response Type](#data-response-type)\n    - [As code (including aide example)](#as-code-including-aide-example-2)\n    - [JSON Representation](#json-representation-2)\n      - [With `Meta`](#with-meta-2)\n  - [Default (Blank) Response Type](#default-blank-response-type)\n    - [As code (including aide example)](#as-code-including-aide-example-3)\n    - [JSON Representation](#json-representation-3)\n      - [With `Meta`](#with-meta-3)\n- [Copyright](#copyright)\n\n---\n\n\n## Installation\n\n```sh\n  go get github.com/ooaklee/reply\n```\n\n## Getting Started\n\nThere are several ways you can integrate `reply` into your application. Below, you will find an example of how you can get the most out of this package.\n\n### How to create a `Replier`\n\nWhen creating a `Replier`, you only have to pass a `reply.ErrorManifest` collection. The collection can be empty or contain as many entries as you'd like.\n\nJust remember, when creating an `Error Response` (Multi or Single), the passed manifest will be used.\n\n```go\n// Have a definition of errors you want to use in your application\nvar (\n\t// errExample404 is an example 404 error\n\terrExample404 = errors.New(\"example-404-error\")\n\t// errExampleDobValidation is an example dob validation error\n\terrExampleDobValidation = errors.New(\"example-dob-validation-error\")\n\t// errExampleNameValidation is an example name validation error\n\terrExampleNameValidation = errors.New(\"example-name-validation-error\")\n\t// errExampleMissing is an example missing error\n\terrExampleMissing = errors.New(\"example-missing-error\")\n\t// errExampleEmailValidation is an example email validation error\n\terrExampleEmailValidation = errors.New(\"example-email-validation-error\")\n)\n\n// (Optional) Create an error manifest to hold correlating errors and their manifest item.\n// These can be also be sourced from relevant packages to populate\n//\n// See how we have to reply.ErrorManifests, on with mulitple\n// items and the other with just one.\nbaseManifest := []reply.ErrorManifest{\n    {\n      errExample404: reply.ErrorManifestItem{Title: \"resource not found\", StatusCode: http.StatusNotFound},\n      errExampleNameValidation: reply.ErrorManifestItem{Title: \"Validation Error\", Detail: \"The name provided does not meet validation requirements\", StatusCode: http.StatusBadRequest, About: \"www.example.com/reply/validation/1011\", Code: \"1011\"},\n    },\n    {errExampleDobValidation: reply.ErrorManifestItem{Title: \"Validation Error\", Detail: \"Check your DoB, and try again.\", Code: \"100YT\", StatusCode: http.StatusBadRequest}},\n    // example using error from another package\n    // {somepackage.ErrNotFound: reply.ErrorManifestItem{Title: \"Not Found\", Detail: \"The requested resource was not found\", Code: \"404\", StatusCode: http.StatusNotFound}},\n  }\n\n// Create Replier to manage the responses going back to consumer(s)\nreplier := reply.NewReplier(baseManifest)\n```\n\n\u003e NOTE - By default, if an `Error Manifest Item` does not have a `StatusCode` set, `reply` will default to `400 (Bad Request)`.\n\n### More about the `ErrorManifest` \n\nThe `ErrorManifest` contains an error and its corresponding `ErrorManifestItem`.\n\nThe `ErrorManifestItem` is used to explicitly define the attributes to include in your response's error object. Like previously mentioned, the `ErrorManifestItem` should be created against the explicit error used in your code or taken from a package you're using.\n\n#### Deeper look into `ErrorManifestItem`\n\n`ErrorManifestItems` will come in various sizes depending on how much information you what to make visible to your consumer.\n\n\u003e It is essential to evaluate the exposure level of your API continuously. Is it something that will be used external to your team/ business, and thus minimal information should be given?\n\nThe key attributes of the `ErrorManifestItem` are:\n\n- **Title** (`string`): Summary of the error being returned. Try keeping it short and sweet.\n\n- **Detail** (`string`): Gives a more descriptive outline of the error, something with more context.\n \n- **StatusCode** (`int`): The [HTTP Status Code](https://httpstatuses.com) associated with respective error. If it's a `5XX` error, it will be the sole error object returned in a `multi error response` scenario.\n \n- **About** (`string`): The URL to a page that gives more context about the error\n\n- **Code** (`string`): The `internal code` (application or business) that's used to identify the error\n\n- **Meta** (`interface{}`): Any additional meta-information you may want to pass with your error object\n\nAssuming an `ErrorManifest` containing the following entry was passed to a `Replier`,\n\n```go\n// manifest item references error defined in previous example\n{errExampleNameValidation: reply.ErrorManifestItem{Title: \"Validation Error\", Detail: \"The name provided does not meet validation requirements\", StatusCode: http.StatusBadRequest, About: \"www.example.com/reply/validation/1011\", Code: \"1011\"}}\n``` \n\nAnd its respective error was passed when creating a new error response (`NewHTTPErrorResponse`). `reply` would return the following JSON response:\n\n```json\n{\n  \"errors\": [\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The name provided does not meet validation requirements\",\n      \"about\": \"www.example.com/reply/validation/1011\",\n      \"status\": \"400\",\n      \"code\": \"1011\"\n    }\n  ]\n}\n```\n\nIf instead, multiple errors were passed to the `NewHTTPMultiErrorResponse` method or errors keys were wrapped and passed to `NewHTTPErrorResponse`, and all had an entry in the `ErrorManifest`, `reply` would return a response similar to the following JSON response:\n\n\n```json\n{\n  \"errors\": [\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The name provided does not meet validation requirements\",\n      \"about\": \"www.example.com/reply/validation/1011\",\n      \"status\": \"400\",\n      \"code\": \"1011\"\n    },\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The email provided does not meet validation requirements\",\n      \"status\": \"400\"\n    }\n  ]\n}\n```\n\n\u003e NOTE - Not all attributes in the `ErrorManifestItem` have to be specified. By default, if a `StatusCode` is not provided in the item `400` would be set. \n\n\u003e NOTE - You can create your own custom error json response shape, by using the `reply.WithTransferObjectError` option when creating your replier. Check the [**example simple api ** implementation (`replierWithCustomTransitionObjs`)](examples/example_simple_api.go) for a working example.\n\n## How to send a response(s) \n\nAt the core, you can use `reply` two send both successful and error responses.\n\nWhen sending an error response, it is essential to make sure you populate the `Error Manifest` passed to the `Replier` with the correct errors source from your code or packages. Otherwise, a `500 - Internal Server Error` response will be sent back to the client by default if it cannot match the passed error in the manifest.\n\n\u003e When matching `errors.Is` is used, the error in the manifest should be the same error as the one passed.\n\nHaving expected `ErrorManifest` entries are especially important for `Multi Error` responses. One unmatched error will return a single `500 - Internal Server Error` instead of the array of passed error responses.\n\n### Making use of error manifest\n\nThere are currently **3** Replier methods that make use of the `Error Manifest`. These methods are `NewHTTPResponse`, `NewHTTPMultiErrorResponse` and `NewHTTPErrorResponse`.\n\n\u003e NOTE - `NewHTTPResponse` is the base of both the `NewHTTPMultiErrorResponse` and `NewHTTPErrorResponse` aides.\n\u003e\n\u003e NOTE - You can get `NewHTTPErrorResponse` to behave like `NewHTTPMultiErrorResponse` by wrapping your error keys with `errors.Join(errs...)`\n\nBelow you will find an example using `NewHTTPResponse`. However, for simplicity, it's recommended you use one of the error aides. The error [aide implementation is outlined **HERE**](#error-response-type).\n\n```go\n\n// ExampleHandler handler to demostrate how to use package for error\n// response\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  // Pass error to Replier's method to return predefined response, else\n  // 500\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer: w,\n    // errExample404 defined in previous example\n    Error:  errExample404,\n  })\n}\n```\n\nWhen the endpoint linked to the handler above is called, you should see the following JSON response.\n\n```JSON\n{\n  \"errors\": [\n    {\n      \"title\": \"resource not found\",\n      \"status\": \"404\"\n    }\n  ]\n}\n```\n\n\u003e `NOTE` - The `baseManifest` was initially declared, and its item represents the response shown below. The status code is both shown in the response body as a string, and it is also set accordingly. \n\n### Sending  \"successful responses\"\n\nThe **3** Replier methods that can send \"successful responses\" are `NewHTTPResponse`, `NewHTTPBlankResponse` and `NewHTTPDataResponse`.\n\n\u003e NOTE - `NewHTTPResponse` is the base of both the `NewHTTPBlankResponse` and `NewHTTPDataResponse` aides.\n\nBelow you will find an example using `NewHTTPResponse`, however for simplicity, it's recommended you use either of the follow aide implementations:\n - [Blank Response Aide](#default-blank-response-type)\n - [Data Response Aide](#data-response-type) \n\n```go\n\n// ExampleGetAllHandler handler to demostrate how to use package for successful \n// response\nfunc ExampleGetAllHandler(w http.ResponseWriter, r *http.Request) {\n\n  // building sample user model\n  type user struct {\n    ID   int    `json:\"id\"`\n    Name string `json:\"name\"`\n  }\n\n  // emulate users pulled from repository\n  mockedQueriedUsers := []user{\n    {ID: 1, Name: \"John Doe\"},\n    {ID: 2, Name: \"Sam Smith\"},\n  }\n\n  // build and sent default formatted JSON response for consumption\n  // by client\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer:     w,\n    Data:       mockedUsers,\n    StatusCode: htttp.StatusOK,\n  })\n}\n```\n\nWhen the endpoint linked to the handler above is called, you should see the following JSON response.\n\n```JSON\n{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"John Doe\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Sam Smith\"\n    }\n  ]\n}\n```\n\n\u003e `NOTE` - Unlike the error use case, successful requests expect the `StatusCode` to be defined when creating a successful response. If you do not provide a status code, 200 will be assumed.\n\u003e \n\u003e It is recommend to use use either the [Blank Response Aide](#default-blank-response-type) or [Data Response Aide](#data-response-type) based on your desired ouput\n\n## Transfer Objects\n\n`Transfer objects` are used to define the shape of various elements within the overall response. In particular, they are used for the `base response object` and the `individual error response object`.\n\nIf desired, users can create their own `transfer object` for the `base` and `individual error` response objects with additional logic.\n\n### Base Transfer Object (`TransferObject`)\n\nThe `Transfer Object` used for the `base response object` **must** satisfy the following interface:\n\n```go\n// TransferObject outlines expected methods of a transfer object\ntype TransferObject interface {\n  SetHeaders(headers map[string]string)\n  SetStatusCode(code int)\n  SetMeta(meta map[string]interface{})\n  SetTokenOne(token string)\n  SetTokenTwo(token string)\n  GetWriter() http.ResponseWriter\n  GetStatusCode() int\n  SetWriter(writer http.ResponseWriter)\n  SetStatus(transferObjectStatus *TransferObjectStatus)\n  RefreshTransferObject() TransferObject\n  SetData(data interface{})\n}\n```\n\nThe interface uses relatively self-explanatory method names. Still, if you want to see an example of how one might create your own `transfer object`, you can find the `default transfer object` used by `reply` [here (defaultReplyTransferObject)](./model.go). \n\nOnce your `transfer object` has been created and is valid, you can overwrite the default `transfer object` in your newly created version by using the following code when declaring your `Replier`:\n\n```go\n// some implementation of your desired transfer object\nvar customTransferObject reply.TransferObject\n\ncustomTransferObject = \u0026foo{}\n\n\n// create a Replier, overwriting the default transfer object\nreplier := reply.NewReplier([]reply.ErrorManifest{}, reply.WithTransferObject(customTransferObject))\n\n// use the new Replier as you otherwise would\n```\n\n\u003e *NOTE:* you can also pass in your custom transfer object with `\u0026foo{}`, for example:\n\u003e\n\u003e `replier := reply.NewReplier([]reply.ErrorManifest{}, reply.WithTransferObject(\u0026foo{}))`\n\n\n\u003e For a live example on how you can use a custom `transfer object`, please look at the [`simple API examples` in this repo](./examples/example_simple_api.go). You are looking out for the `fooReplyTransferObject` implementation.\n\n### Error Transfer Object (`TransferObjectError`)\n\nThe `Transfer Object` used for the `individual error response object` **must** satisfy the following interface:\n\n```go\n// TransferObjectError outlines expected methods of a transfer object error\ntype TransferObjectError interface {\n  SetTitle(title string)\n  GetTitle() string\n  SetDetail(detail string)\n  GetDetail() string\n  SetAbout(about string)\n  GetAbout() string\n  SetStatusCode(status int)\n  GetStatusCode() string\n  SetCode(code string)\n  GetCode() string\n  SetMeta(meta interface{})\n  GetMeta() interface{}\n  RefreshTransferObject() TransferObjectError\n}\n```\n\nThe interface uses relatively self-explanatory method names. Look at the [deeper dive of the Error Manifest Item](#deeper-look-into-errormanifestitem) to better understand how these methods are used. \n\nSuppose you want to see an example of how one might create your own `transfer object error`. In that case, you can find the `default transfer object error` used by `reply` [here (defaultReplyTransferObjectError)](./model.go). \n\nYou can overwrite the default `transfer object error` used by your `Replier` by using the following code when declaring your `Replier`:\n\n```go\n// some implementation of your desired transfer object\nvar customTransferObjectError reply.TransferObjectError\n\ncustomTransferObjectError = \u0026bar{}\n\n\n// create a Replier, overwriting the default transfer object error (error transfer object)\nreplier := reply.NewReplier([]reply.ErrorManifest{}, reply.WithTransferObjectError(customTransferObjectError))\n\n// use the new Replier as you otherwise would\n```\n\n\u003e *NOTE:* you can also pass in your custom transfer object with `\u0026bar{}`, for example:\n\u003e\n\u003e `replier := reply.NewReplier([]reply.ErrorManifest{}, reply.customTransferObjectError(\u0026bar{}))`\n\n\n\u003e For a live example on how you can use a custom `transfer object error` in combination with a custom `transfer object`, please look at the [`simple API examples` in this repo](./examples/example_simple_api.go). You are looking out for the `replierWithCustomTransitionObjs` implementation.\n\u003e\n\u003e You can set your custom `transfer object error` individually, as shown above.\n\n\n## Response Types\n\nThere are currently four core response types supported by `reply`. They are the `Error`, `Token`, `Data` and `Default` response types. Each type has its JSON representation defined through a [`Transfer Object`](#transfer-objects).\n\n\u003e NOTE: Unless otherwise stated, the `Transfer Objects` assumed will be the [default transfer object (defaultReplyTransferObject)](./model.go) and [default transfer object error (defaultReplyTransferObjectError)](./model.go).\n\n### Universal Attributes\n\nAll core response types share universal attributes, which you can set in addition to their outputs. These include:\n- Headers\n- Meta\n- Status Code\n\n\u003e NOTE - `Status Code` is set at different levels dependant on `response type`. For example, the `error response type` is handled in the [`ErrorManifest`](#more-about-the-errormanifest).\n\n### Error Response Type\n\nThe `Error` response notifies the consumer when an error/ unexpected behaviour has occurred on the API. There are **2** types of `Error Response Types`, `NewHTTPErrorResponse` and `NewHTTPMultiErrorResponse`.\n\n\u003e Where `NewHTTPMultiErrorResponse` explicitly expects a slice of errors, `NewHTTPErrorResponse` can also return multi errors response by wrapping the manifest errors with `errors.Join(errs...)`.\n\nThe error response object forwarded to the consumer is sourced from the [error manifest](#more-about-the-errormanifest). In the event the error's string\nrepresentation isn't in the manifest; `reply` will return the consumer a \"500 - Internal Server Error\" response.\n\n#### As code (including aide example)\n\nTo create an individual `error` response use the following code snippet:\n\n```go\n// create error manifest using errors defined in application (see previous example for error definitions)\nbaseManifest := []reply.ErrorManifest{\n  {errExample404: reply.ErrorManifestItem{Title: \"resource not found\", StatusCode: http.StatusNotFound},\n    errExampleNameValidation: reply.ErrorManifestItem{Title: \"Validation Error\", Detail: \"The name provided does not meet validation requirements\", StatusCode: http.StatusBadRequest, About: \"www.example.com/reply/validation/1011\", Code: \"1011\"},\n  },\n  errExampleDobValidation: reply.ErrorManifestItem{Title: \"Validation Error\", Detail: \"Check your DoB, and try again.\", Code: \"100YT\", StatusCode: http.StatusBadRequest},\n}\n\n// create Replier based on error manifest\nreplier := reply.NewReplier(baseManifest)\n\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer: w,\n    Error:  errExample404,\n  })\n}\n```\n\nIf you wanted to send a `multi error response`, you could use the following, assuming the same `Replier` from above is being used:\n\n```go\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  // errors returned\n  exampleErrs := []errors{\n    errExampleNameValidation,\n    errExampleDobValidation,\n  }\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer: w,\n    Errors: exampleErrs,\n  })\n}\n\n```\n\nYou can also send a `multi error response` with a single error by wrapping the error keys with `errors.Join(errs...)`:\n\n```go\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  // errors returned\n  exampleWrappedErr := errors.Join(errExampleNameValidation, errExampleEmailValidation)\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer: w,\n    Error: exampleWrappedErr,\n  })\n}\n\n```\n\nFor readability and simplicity, you can use the `HTTP error response aides`. You can find code snippets using these aides below:\n\n- `Individual Error`\n\n```go\n// inside of the request handler\n_ = replier.NewHTTPErrorResponse(w, exampleErr)\n```\n\n- `Multi Error`\n\n```go\n// inside of the request handler\n_ = replier.NewHTTPMultiErrorResponse(w, exampleErrs)\n```\n\nYou can also add additional `headers` and `meta data` to the response by using the optional `WithHeaders` and/ or `WithMeta` response attributes respectively. For example:\n\n```go\n_ = replier.NewHTTPErrorResponse(w, exampleErr, reply.WithMeta(map[string]interface{}{\n    \"example\": \"meta in error reponse\",\n  }))\n```\n\n**OR**\n\n```go\n_ = replier.NewHTTPMultiErrorResponse(w, exampleErrs, reply.WithMeta(map[string]interface{}{\n    \"example\": \"meta in error reponse\",\n  }))\n```\n\n#### JSON Representation\n\n`Error` responses are returned with the format. The following responses are based on the examples above, so your response content will vary.\n\n- `Individual Error`\n\n```JSON\n{\n  \"errors\": [\n    {\n      \"title\": \"resource not found\",\n      \"status\": \"404\"\n    }\n  ]\n}\n```\n\n- `Multi Error`\n\n```json\n{\n  \"errors\": [\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The name provided does not meet validation requirements\",\n      \"about\": \"www.example.com/reply/validation/1011\",\n      \"status\": \"400\",\n      \"code\": \"1011\"\n    },\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The email provided does not meetvalidation requirements\",\n      \"status\": \"400\"\n    }\n  ]\n}\n```\n\n##### With `Meta`\n\nWhen a `meta` is also declared, the response will have the following format. It can be as big or small as needed.\n\n- `Individual Error`\n\n```JSON\n{\n  \"errors\": [\n    {\n      \"title\": \"resource not found\",\n      \"status\": \"404\"\n    }\n  ],\n  \"meta\": {\n    \"example\": \"meta in error reponse\"\n  }\n}\n```\n\n- `Multi Error`\n\n```json\n{\n  \"errors\": [\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The name provided does not meet validation requirements\",\n      \"about\": \"www.example.com/reply/validation/1011\",\n      \"status\": \"400\",\n      \"code\": \"1011\"\n    },\n    {\n      \"title\": \"Validation Error\",\n      \"detail\": \"The email provided does not meetvalidation requirements\",\n      \"status\": \"400\"\n    }\n  ],\n  \"meta\": {\n    \"example\": \"meta in error reponse\"\n  }\n}\n```\n\n### Token Response Type\n\nThe `token` response sends the consumer tokens. Currently, it is limited to **2** tokens, and with the default `Transfer Object`, `TokenOne` represents `access_token`, and `TokenTwo` represents `refresh_token`. However, if you use other ID/ JSON attributes to describe your tokens for your API, you can [**create a `Custom Transfer Object`**](#transfer-objects).\n\nAgain, when using the default `Transfer Object`, the supported `TokenOne` and `TokenTwo` represent `acccess_token` and `refresh_token`, respectively. If either is passed in the response request, `reply` will default to this response type.\n\n#### As code (including aide example)\n\nTo create a `token` response use the following code snippet:\n\n```go\nreplier := reply.NewReplier([]reply.ErrorManifest{})\n\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  // do something to get tokens\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer:     w,\n    TokenOne:   \"08a0a043-b532-4cea-8117-364739f2d994\",\n    TokenTwo:   \"08b29914-09a8-4a4a-8aa5-b1ffaff266e6\",\n    StatusCode: 200,\n  })\n}\n```\n\nFor readability and simplicity, you can use the `HTTP token response aide`. You can find a code snippet using this aide below:\n\n```go\n// inside of the request handler\n_ = replier.NewHTTPTokenResponse(w, 200, \"08a0a043-b532-4cea-8117-364739f2d994\", \"08b29914-09a8-4a4a-8aa5-b1ffaff266e6\")\n```\n\nYou can also add additional `headers` and `meta data` to the response by using the optional `WithHeaders` and/ or `WithMeta` response attributes respectively. For example:\n\n```go\n_ = replier.NewHTTPTokenResponse(w, 200, \"08a0a043-b532-4cea-8117-364739f2d994\", \"08b29914-09a8-4a4a-8aa5-b1ffaff266e6\", reply.WithMeta(map[string]interface{}{\n \"example\": \"meta in token reponse\",\n}))\n```\n\n\u003e NOTE: If you only want to return one token, pass an empty string, i.e. `\"\"`. Although, you must give at least one token string. \n\n#### JSON Representation\n\n`Error` responses are returned with the format.\n\n```JSON\n{\n  \"access_token\": \"08a0a043-b532-4cea-8117-364739f2d994\",\n  \"refresh_token\": \"08b29914-09a8-4a4a-8aa5-b1ffaff266e6\"\n}\n```\n\n##### With `Meta`\n\nWhen a `meta` is also declared, the response will have the following format. It can be as big or small as needed.\n\n```JSON\n{\n  \"access_token\": \"08a0a043-b532-4cea-8117-364739f2d994\",\n  \"refresh_token\": \"08b29914-09a8-4a4a-8aa5-b1ffaff266e6\",\n  \"meta\": {\n    \"example\": \"meta in token reponse\"\n  }\n}\n```\n\n### Data Response Type\n\nThe `data` response can be seen as a *successful* response. It parses the passed struct into its JSON representation and passes it to the consumer in the JSON response. The JSON response below will represent a response if the data passed was a user struct with the:\n- `id` 1\n- `name` john doe\n- `dob` 1/1/1970\n\n#### As code (including aide example)\n\nTo create a `data` response use the following code snippet:\n\n```go\ntype user struct {\n  id   int    `json:\"id\"`\n  name string `json:\"name\"`\n  dob  string `json:\"dob\"`\n}\n\nreplier := reply.NewReplier([]reply.ErrorManifest{})\n\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  u := user{\n    id:   1,\n    name: \"john doe\",\n    dob:  \"1/1/1970\",\n  }\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer:     w,\n    Data:       u,\n    StatusCode: 201,\n  })\n}\n```\n\n\nFor readability and simplicity, you can use the `HTTP data (successful) response aide`. You can find a code snippet using this aide below:\n\n```go\n// inside of the request handler\n_ = replier.NewHTTPDataResponse(w, 201, u)\n```\n\nYou can also add additional `headers` and `meta data` to the response by using the optional `WithHeaders` and/ or `WithMeta` response attributes respectively. For example:\n\n```go\n_ = replier.NewHTTPDataResponse(w, 201, u, reply.WithMeta(map[string]interface{}{\n    \"example\": \"meta in data reponse\",\n  }))\n```\n\n#### JSON Representation\n\n`Data` responses are returned with the format.\n\n```JSON\n{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"john doe\",\n    \"dob\": \"1/1/1970\"\n  }\n}\n```\n\n##### With `Meta`\n\nWhen a `meta` is also declared, the response will have the following format. It can be as big or small as needed.\n\n```JSON\n{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"john doe\",\n    \"dob\": \"1/1/1970\"\n  },\n  \"meta\": {\n    \"example\": \"meta in data reponse\"\n  }\n}\n```\n\n### Default (Blank) Response Type\n\nThe `default` (blank) response returns `\"{}\"` with a status code of `200` if no `error`, `tokens`, `data` and `status code` is passed. If desired, another `status code` can be specified with `default` responses.\n\n#### As code (including aide example)\n\nTo create a `default` response use the following code snippet:\n\n```go\nreplier := reply.NewReplier([]reply.ErrorManifest{})\n\nfunc ExampleHandler(w http.ResponseWriter, r *http.Request) {\n\n  _ = replier.NewHTTPResponse(\u0026reply.NewResponseRequest{\n    Writer:     w,\n    StatusCode: 200,\n  })\n}\n```\n\nFor readability and simplicity, you can use the `HTTP default (blank) response aide`. You can find a code snippet using this aide below:\n\n```go\n// inside of the request handler\n_ = replier.NewHTTPBlankResponse(w, 200)\n```\n\nYou can also add additional `headers` and `meta data` to the response by using the optional `WithHeaders` and/ or `WithMeta` response attributes respectively. For example:\n\n```go\n_ = replier.NewHTTPBlankResponse(w, 200, reply.WithMeta(map[string]interface{}{\n    \"example\": \"meta in default reponse\",\n  }))\n```\n\n\n#### JSON Representation\n\n`Default` responses are returned with the format.\n\n```JSON\n{\n  \"data\": \"{}\"\n}\n```\n\n##### With `Meta`\n\nWhen a `meta` is also declared, the response will have the following format. It can be as big or small as needed.\n\n```JSON\n{\n  \"data\": \"{}\",\n  \"meta\": {\n    \"example\": \"meta in default reponse\"\n  }\n}\n```\n\n## Copyright\n\nCopyright (C) 2021 by Leon Silcott \u003cleon@boasi.io\u003e.\n\nreply library released under MIT License.\nSee [LICENSE](https://github.com/ooaklee/reply/blob/master/LICENSE) for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fooaklee%2Freply","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fooaklee%2Freply","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fooaklee%2Freply/lists"}