{"id":13481414,"url":"https://github.com/oapi-codegen/oapi-codegen","last_synced_at":"2025-05-14T00:10:17.759Z","repository":{"id":38184567,"uuid":"173009358","full_name":"oapi-codegen/oapi-codegen","owner":"oapi-codegen","description":"Generate Go client and server boilerplate from OpenAPI 3 specifications","archived":false,"fork":false,"pushed_at":"2025-05-05T14:55:13.000Z","size":15799,"stargazers_count":7046,"open_issues_count":679,"forks_count":925,"subscribers_count":39,"default_branch":"main","last_synced_at":"2025-05-05T15:58:31.536Z","etag":null,"topics":["go","golang","openapi","openapi-codegen","openapi-generator","openapi3","rest-api","rest-api-client","swagger"],"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/oapi-codegen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["oapi-codegen","jamietanna"],"open_collective":"oapi-codegen"}},"created_at":"2019-02-27T23:59:59.000Z","updated_at":"2025-05-05T13:50:09.000Z","dependencies_parsed_at":"2023-10-16T03:06:27.737Z","dependency_job_id":"2df02b1d-9d3a-4cc7-86d7-8c593a128395","html_url":"https://github.com/oapi-codegen/oapi-codegen","commit_stats":{"total_commits":782,"total_committers":251,"mean_commits":"3.1155378486055776","dds":0.8043478260869565,"last_synced_commit":"fd1f9b3e448846c1c4749f5c7eaae60e2be7a02c"},"previous_names":["oapi-codegen/oapi-codegen"],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oapi-codegen%2Foapi-codegen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oapi-codegen%2Foapi-codegen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oapi-codegen%2Foapi-codegen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oapi-codegen%2Foapi-codegen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oapi-codegen","download_url":"https://codeload.github.com/oapi-codegen/oapi-codegen/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254044295,"owners_count":22005129,"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":["go","golang","openapi","openapi-codegen","openapi-generator","openapi3","rest-api","rest-api-client","swagger"],"created_at":"2024-07-31T17:00:51.625Z","updated_at":"2025-05-14T00:10:17.748Z","avatar_url":"https://github.com/oapi-codegen.png","language":"Go","readme":"# `oapi-codegen`\n\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9450/badge)](https://www.bestpractices.dev/projects/9450)\n\n`oapi-codegen` is a command-line tool and library to convert OpenAPI specifications to Go code, be it [server-side implementations](#generating-server-side-boilerplate), [API clients](#generating-api-clients), or simply [HTTP models](#generating-api-models).\n\nUsing `oapi-codegen` allows you to reduce the boilerplate required to create or integrate with services based on [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md), and instead focus on writing your business logic, and working on the real value-add for your organisation.\n\nWith `oapi-codegen`, there are a few [Key Design Decisions](#key-design-decisions) we've made, including:\n\n- idiomatic Go, where possible\n- fairly simple generated code, erring on the side of duplicate code over nicely refactored code\n- supporting as much of OpenAPI 3.x as is possible, alongside Go's type system\n\n`oapi-codegen` is one part of a wider ecosystem, which can be found described in further detail in the [oapi-codegen organisation on GitHub](https://github.com/oapi-codegen).\n\n⚠️ This README may be for the latest development version, which may contain unreleased changes. Please ensure you're looking at the README for the latest release version.\n\n## Action Required: The repository for this project has changed\n\nAs announced in [May 2024](https://github.com/oapi-codegen/oapi-codegen/discussions/1605),\nwe have moved the project from the deepmap organization to our own organization, and you will need to update your\nimport paths to pull updates past this point. You need to do a recursive search/replace from\n`github.com/deepmap/oapi-codegen/v2` to `github.com/oapi-codegen/oapi-codegen/v2`.\n\n\u003e [!IMPORTANT]\n\u003e `oapi-codegen` moved to its new home with the version tag `v2.3.0`.\n\nIf you are using `v2.2.0` or below, please install like so:\n\n```sh\n# for the binary install\ngo install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@v2.2.0\n```\n\nIf you are using `v2.3.0` or above, please install like so, using the new module import path:\n\n```sh\n# for the binary install\ngo install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest\n```\n\n## Install\n\n## For Go 1.24+\n\nIt is recommended to follow [the `go tool` support available from Go 1.24+](https://www.jvt.me/posts/2025/01/27/go-tools-124/) for managing the dependency of `oapi-codegen` alongside your core application.\n\nTo do this, you run `go get -tool`:\n\n```sh\n$ go get -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest\n# this will then modify your `go.mod`\n```\n\nFrom there, each invocation of `oapi-codegen` would be used like so:\n\n```go\n//go:generate go tool oapi-codegen -config cfg.yaml ../../api.yaml\n```\n\n## Prior to Go 1.24\n\nIt is recommended to follow [the `tools.go` pattern](https://www.jvt.me/posts/2022/06/15/go-tools-dependency-management/) for managing the dependency of `oapi-codegen` alongside your core application.\n\nThis would give you a `tools/tools.go`:\n\n```go\n//go:build tools\n// +build tools\n\npackage main\n\nimport (\n\t_ \"github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen\"\n)\n```\n\nThen, each invocation of `oapi-codegen` would be used like so:\n\n```go\n//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml ../../api.yaml\n```\n\nAlternatively, you can install it as a binary with:\n\n```sh\n$ go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest\n$ oapi-codegen -version\n```\n\nWhich then means you can invoke it like so:\n\n```go\n//go:generate oapi-codegen --config=config.yaml ../../api.yaml\n```\n\nNote that you can also [move your `tools.go` into its own sub-module](https://www.jvt.me/posts/2024/09/30/go-tools-module/) to reduce the impact on your top-level `go.mod`.\n\n### Pinning to commits\n\nWhile the project does not ([yet](https://github.com/oapi-codegen/oapi-codegen/issues/1519)) have a defined release cadence, there may be cases where you want to pull in yet-unreleased changes to your codebase.\n\nTherefore, you may want to pin your dependency on `oapi-codegen` to a given commit hash, rather than a tag.\n\nThis is **officially recommended** for consumers of `oapi-codegen`, who want features/bug fixes that haven't yet been released.\n\nWe aim to keep the default branch ready-to-release so you should be able to safely pin.\n\nTo do so, you can run:\n\n```sh\n# pin to the latest version on the default branch\n$ go get github.com/oapi-codegen/oapi-codegen/v2@main\n# alternatively, to a commit hash i.e. https://github.com/oapi-codegen/oapi-codegen/commit/71e916c59688a6379b5774dfe5904ec222b9a537\n$ go get github.com/oapi-codegen/oapi-codegen/v2@71e916c59688a6379b5774dfe5904ec222b9a537\n```\n\nThis will then make a change such as:\n\n```diff\ndiff --git go.mod go.mod\nindex 44f29a4..436a780 100644\n--- go.mod\n+++ go.mod\n@@ -2,21 +2,20 @@\n-require github.com/oapi-codegen/oapi-codegen/v2 v2.1.0\n+require github.com/oapi-codegen/oapi-codegen/v2 v2.1.1-0.20240331212514-80f0b978ef16\n```\n\n## Usage\n\n`oapi-codegen` is largely configured using a YAML configuration file, to simplify the number of flags that users need to remember, and to make reading the `go:generate` command less daunting.\n\nFor full details of what is supported, it's worth checking out [the GoDoc for `codegen.Configuration`](https://pkg.go.dev/github.com/oapi-codegen/oapi-codegen/v2/pkg/codegen#Configuration).\n\nWe also have [a JSON Schema](configuration-schema.json) that can be used by IDEs/editors with the Language Server Protocol (LSP) to perform intelligent suggestions, i.e.:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: api\n# ...\n```\n\n### Backwards compatibility\n\nAlthough we strive to retain backwards compatibility - as a project that's using a stable API per SemVer - there are sometimes opportunities we must take to fix a bug that could cause a breaking change for [people relying upon the behaviour](https://xkcd.com/1172/).\n\nIn this case, we will expose a [compatibility option](https://pkg.go.dev/github.com/oapi-codegen/oapi-codegen/v2/pkg/codegen#CompatibilityOptions) to restore old behaviour.\n\n## Features\n\nAt a high level, `oapi-codegen` supports:\n\n- Generating server-side boilerplate for [a number of servers](#supported-servers) ([docs](#generating-server-side-boilerplate))\n- Generating client API boilerplate ([docs](#generating-api-clients))\n- Generating the types ([docs](#generating-api-models))\n- Splitting large OpenAPI specs across multiple packages([docs](#import-mapping))\n  - This is also known as \"Import Mapping\" or \"external references\" across our documentation / discussion in GitHub issues\n\n## What does it look like?\n\nBelow we can see a trimmed down example taken from the OpenAPI Petstore [example](examples/petstore-expanded/stdhttp/api/petstore.gen.go):\n\n```go\n// generated code\n\ntype ServerInterface interface {\n\t// ...\n\t// Returns all pets\n\t// (GET /pets)\n\tFindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams)\n\t// ...\n}\n\n// FindPets operation middleware\nfunc (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) {\n\n\tvar err error\n\n\t// Parameter object where we will unmarshal all parameters from the context\n\tvar params FindPetsParams\n\n\t// ------------- Optional query parameter \"tags\" -------------\n\n\terr = runtime.BindQueryParameter(\"form\", true, false, \"tags\", r.URL.Query(), \u0026params.Tags)\n\tif err != nil {\n\t\tsiw.ErrorHandlerFunc(w, r, \u0026InvalidParamFormatError{ParamName: \"tags\", Err: err})\n\t\treturn\n\t}\n\n\t// ------------- Optional query parameter \"limit\" -------------\n\n\terr = runtime.BindQueryParameter(\"form\", true, false, \"limit\", r.URL.Query(), \u0026params.Limit)\n\tif err != nil {\n\t\tsiw.ErrorHandlerFunc(w, r, \u0026InvalidParamFormatError{ParamName: \"limit\", Err: err})\n\t\treturn\n\t}\n\n\thandler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tsiw.Handler.FindPets(w, r, params)\n\t}))\n\n\tfor _, middleware := range siw.HandlerMiddlewares {\n\t\thandler = middleware(handler)\n\t}\n\n\thandler.ServeHTTP(w, r)\n}\n\n// HandlerWithOptions creates http.Handler with additional options\nfunc HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.Handler {\n\tm := options.BaseRouter\n\n\tif m == nil {\n\t\tm = http.NewServeMux()\n\t}\n\tif options.ErrorHandlerFunc == nil {\n\t\toptions.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t}\n\t}\n\n\twrapper := ServerInterfaceWrapper{\n\t\tHandler:            si,\n\t\tHandlerMiddlewares: options.Middlewares,\n\t\tErrorHandlerFunc:   options.ErrorHandlerFunc,\n\t}\n\n\tm.HandleFunc(\"GET \"+options.BaseURL+\"/pets\", wrapper.FindPets)\n\n\treturn m\n}\n```\n\nThen, in your own code, you implement the underlying logic for the `FindPets` implementation:\n\n```go\ntype PetStore struct {\n\tPets   map[int64]Pet\n\tNextId int64\n\tLock   sync.Mutex\n}\n\n// Make sure we conform to ServerInterface\n\nvar _ ServerInterface = (*PetStore)(nil)\n\nfunc NewPetStore() *PetStore {\n\treturn \u0026PetStore{\n\t\tPets:   make(map[int64]Pet),\n\t\tNextId: 1000,\n\t}\n}\n\n// FindPets implements all the handlers in the ServerInterface\nfunc (p *PetStore) FindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams) {\n\tp.Lock.Lock()\n\tdefer p.Lock.Unlock()\n\n\tvar result []Pet\n\n\tfor _, pet := range p.Pets {\n\t\tif params.Tags != nil {\n\t\t\t// If we have tags,  filter pets by tag\n\t\t\tfor _, t := range *params.Tags {\n\t\t\t\tif pet.Tag != nil \u0026\u0026 (*pet.Tag == t) {\n\t\t\t\t\tresult = append(result, pet)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Add all pets if we're not filtering\n\t\t\tresult = append(result, pet)\n\t\t}\n\n\t\tif params.Limit != nil {\n\t\t\tl := int(*params.Limit)\n\t\t\tif len(result) \u003e= l {\n\t\t\t\t// We're at the limit\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\t_ = json.NewEncoder(w).Encode(result)\n}\n```\n\nAs we can see, `oapi-codegen` simplifies some of the boilerplate by taking parameters out of the request and instead allows us to focus on the implementation.\n\nYou'll note that there's still a bit more marshaling of request/response data, which is further reduced by using the [Strict server](#strict-server) functionality.\n\n\u003ca name=\"what-does-it-look-like-strict\"\u003e\u003c/a\u003e\nWhen using the strict server, you'll have the following generated code:\n\n```go\n// StrictServerInterface represents all server handlers.\ntype StrictServerInterface interface {\n\t// ...\n\t// Returns all pets\n\t// (GET /pets)\n\tFindPets(ctx context.Context, request FindPetsRequestObject) (FindPetsResponseObject, error)\n\t// ...\n}\n\nfunc NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface {\n\treturn \u0026strictHandler{ssi: ssi, middlewares: middlewares, options: options}\n}\n\n// FindPets operation middleware\nfunc (sh *strictHandler) FindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams) {\n\tvar request FindPetsRequestObject\n\n\trequest.Params = params\n\n\thandler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {\n\t\treturn sh.ssi.FindPets(ctx, request.(FindPetsRequestObject))\n\t}\n\tfor _, middleware := range sh.middlewares {\n\t\thandler = middleware(handler, \"FindPets\")\n\t}\n\n\tresponse, err := handler(r.Context(), w, r, request)\n\n\tif err != nil {\n\t\tsh.options.ResponseErrorHandlerFunc(w, r, err)\n\t} else if validResponse, ok := response.(FindPetsResponseObject); ok {\n\t\tif err := validResponse.VisitFindPetsResponse(w); err != nil {\n\t\t\tsh.options.ResponseErrorHandlerFunc(w, r, err)\n\t\t}\n\t} else if response != nil {\n\t\tsh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf(\"unexpected response type: %T\", response))\n\t}\n}\n```\n\nThen, in your own code, you implement the underlying logic for the `FindPets` implementation:\n\n```go\n// Make sure we conform to StrictServerInterface\n\nvar _ StrictServerInterface = (*PetStore)(nil)\n\nfunc NewPetStore() *PetStore {\n\treturn \u0026PetStore{\n\t\tPets:   make(map[int64]Pet),\n\t\tNextId: 1000,\n\t}\n}\n\n// FindPets implements all the handlers in the ServerInterface\nfunc (p *PetStore) FindPets(ctx context.Context, request FindPetsRequestObject) (FindPetsResponseObject, error) {\n\tp.Lock.Lock()\n\tdefer p.Lock.Unlock()\n\n\tvar result []Pet\n\n\tfor _, pet := range p.Pets {\n\t\tif request.Params.Tags != nil {\n\t\t\t// If we have tags,  filter pets by tag\n\t\t\tfor _, t := range *request.Params.Tags {\n\t\t\t\tif pet.Tag != nil \u0026\u0026 (*pet.Tag == t) {\n\t\t\t\t\tresult = append(result, pet)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Add all pets if we're not filtering\n\t\t\tresult = append(result, pet)\n\t\t}\n\n\t\tif request.Params.Limit != nil {\n\t\t\tl := int(*request.Params.Limit)\n\t\t\tif len(result) \u003e= l {\n\t\t\t\t// We're at the limit\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn FindPets200JSONResponse(result), nil\n}\n```\n\nWe can see that this provides the best means to focus on the implementation of the business logic within the endpoint, rather than (un)marshalling types to and from JSON, or wrangling cookies or headers.\n\n## Key design decisions\n\n- Produce an interface that can be satisfied by your implementation, with reduced boilerplate\n- Bulk processing and parsing of OpenAPI document in Go\n- Resulting output is using Go's `text/template`s, which are user-overridable\n- Attempts to produce Idiomatic Go\n- Single-file output\n- Support multiple OpenAPI files by having a package-per-OpenAPI file\n- Support of OpenAPI 3.0\n  - OpenAPI 3.1 support is [awaiting upstream support](https://github.com/oapi-codegen/oapi-codegen/issues/373)\n  - Note that this does not include OpenAPI 2.0 (aka Swagger)\n- Extract parameters from requests, to reduce work required by your implementation\n- Implicit `additionalProperties` are ignored by default ([more details](#additional-properties-additionalproperties))\n- Prune unused types by default\n\n## Generating server-side boilerplate\n\n`oapi-codegen` shines by making it fairly straightforward (note that this is a purposeful choice of wording here - we want to avoid words like \"easy\") to generate the server-side boilerplate for a backend API.\n\nBelow you can find the supported servers, and more information about how to implement a server using them.\n\nTo provide you a fully Test Driven Development style test harness to confirm you are following the specification, you could use a tool such as [openapi.tanna.dev/go/validator](https://openapi.tanna.dev/go/validator/), or craft your own.\n\n### Supported Servers\n\nRight now, we support the following servers, and are supportive of adding new servers, too!\n\n\u003ctable\u003e\n\n\u003ctr\u003e\n\u003cth\u003e\nServer\n\u003c/th\u003e\n\u003cth\u003e\n\u003ccode\u003egenerate\u003c/code\u003e flag to enable code generation\n\u003c/th\u003e\n\u003cth\u003e\nExample usage\n\u003c/th\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Chi](https://github.com/go-chi/chi)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003echi-server\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd\u003e\n\n\nFor a Chi server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  chi-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Chi docs](#impl-chi).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Echo](https://github.com/labstack/echo)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003eecho-server\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd\u003e\n\nFor an Echo server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  echo-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Echo docs](#impl-echo).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Fiber](https://github.com/gofiber/fiber)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003efiber-server\u003c/code\u003e\n\u003c/td\u003e\n\n\u003ctd\u003e\n\nFor a Fiber server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  fiber-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Fiber docs](#impl-fiber).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Gin](https://github.com/gin-gonic/gin)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003egin-server\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd\u003e\n\nFor a Gin server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  gin-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Gin docs](#impl-gin).\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[gorilla/mux](https://github.com/gorilla/mux)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003egorilla-server\u003c/code\u003e\n\u003c/td\u003e\n\n\u003ctd\u003e\n\nFor a gorilla/mux server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  gorilla-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the gorilla/mux docs](#impl-gorillamux).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Iris](https://github.com/kataras/iris)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003eiris-server\u003c/code\u003e\n\u003c/td\u003e\n\n\u003ctd\u003e\n\nFor a Iris server, you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  iris-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Iris docs](#impl-iris).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[1.22+ `net/http`](https://pkg.go.dev/net/http)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\u003ccode\u003estd-http-server\u003c/code\u003e\n\u003c/td\u003e\n\n\u003ctd\u003e\n\nTo use purely `net/http` (for Go 1.22+), you will want a configuration file such as:\n\n```yaml\n# yaml-language-server: ...\npackage: api\ngenerate:\n  std-http-server: true\n  models: true\noutput: gen.go\n```\n\nTo implement this, check out [the Go 1.22+ `net/http` docs](#impl-stdhttp).\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003c/table\u003e\n\n### Go 1.22+ `net/http`\n\u003ca name=\"impl-stdhttp\"\u003e\u003c/a\u003e\n\nAs of Go 1.22, enhancements have been made to the routing of the `net/http` package in the standard library, which makes it a great starting point for implementing a server with, before needing to reach for another router or a full framework.\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(w http.ResponseWriter, r *http.Request)\n}\n\nfunc HandlerFromMux(si ServerInterface, m ServeMux) http.Handler {\n\treturn HandlerWithOptions(si, StdHTTPServerOptions{\n\t\tBaseRouter: m,\n\t})\n}\n\n// HandlerWithOptions creates http.Handler with additional options\nfunc HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.Handler {\n\tm := options.BaseRouter\n\n\t// ... omitted for brevity\n\n\tm.HandleFunc(\"GET \"+options.BaseURL+\"/ping\", wrapper.GetPing)\n\n\treturn m\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/stdhttp/api/impl.go):\n\n```go\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(w http.ResponseWriter, r *http.Request) {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\t_ = json.NewEncoder(w).Encode(resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/stdhttp/api\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\tr := http.NewServeMux()\n\n\t// get an `http.Handler` that we can use\n\th := api.HandlerFromMux(server, r)\n\n\ts := \u0026http.Server{\n\t\tHandler: h,\n\t\tAddr:    \"0.0.0.0:8080\",\n\t}\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(s.ListenAndServe())\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n\u003e [!NOTE]\n\u003e If you feel like you've done everything right, but are still receiving `404 page not found` errors, make sure that you've got the `go` directive in your `go.mod` updated to:\n\n```go.mod\ngo 1.22\n```\n\n\u003c/details\u003e\n\n### Chi\n\u003ca name=\"impl-chi\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(w http.ResponseWriter, r *http.Request)\n}\n\n// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.\nfunc HandlerFromMux(si ServerInterface, r *mux.Router) http.Handler {\n\treturn HandlerWithOptions(si, ChiServerOptions{\n\t\tBaseRouter: r,\n\t})\n}\n\n// HandlerWithOptions creates http.Handler with additional options\nfunc HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler {\n\tr := options.BaseRouter\n\n\t// ...\n\n\tr.Group(func(r chi.Router) {\n\t\tr.Get(options.BaseURL+\"/ping\", wrapper.GetPing)\n\t})\n\n\treturn r\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/chi/api/impl.go):\n\n```go\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(w http.ResponseWriter, r *http.Request) {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\t_ = json.NewEncoder(w).Encode(resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/chi/api\"\n\t\"github.com/go-chi/chi/v5\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\tr := chi.NewMux()\n\n\t// get an `http.Handler` that we can use\n\th := api.HandlerFromMux(server, r)\n\n\ts := \u0026http.Server{\n\t\tHandler: h,\n\t\tAddr:    \"0.0.0.0:8080\",\n\t}\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(s.ListenAndServe())\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### gorilla/mux\n\u003ca name=\"impl-gorillamux\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(w http.ResponseWriter, r *http.Request)\n}\n\n// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.\nfunc HandlerFromMux(si ServerInterface, r *mux.Router) http.Handler {\n\treturn HandlerWithOptions(si, GorillaServerOptions{\n\t\tBaseRouter: r,\n\t})\n}\n\n// HandlerWithOptions creates http.Handler with additional options\nfunc HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.Handler {\n\tr := options.BaseRouter\n\n\t// ...\n\n\tr.HandleFunc(options.BaseURL+\"/ping\", wrapper.GetPing).Methods(\"GET\")\n\n\treturn r\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/gorillamux/api/impl.go):\n\n```go\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(w http.ResponseWriter, r *http.Request) {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\t_ = json.NewEncoder(w).Encode(resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/gorillamux/api\"\n\t\"github.com/gorilla/mux\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\tr := mux.NewRouter()\n\n\t// get an `http.Handler` that we can use\n\th := api.HandlerFromMux(server, r)\n\n\ts := \u0026http.Server{\n\t\tHandler: h,\n\t\tAddr:    \"0.0.0.0:8080\",\n\t}\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(s.ListenAndServe())\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### Echo server\n\u003ca name=\"impl-echo\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(ctx echo.Context) error\n}\n\n// This is a simple interface which specifies echo.Route addition functions which\n// are present on both echo.Echo and echo.Group, since we want to allow using\n// either of them for path registration\ntype EchoRouter interface {\n\t// ...\n\tGET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route\n\t// ...\n}\n\n// RegisterHandlers adds each server route to the EchoRouter.\nfunc RegisterHandlers(router EchoRouter, si ServerInterface) {\n\tRegisterHandlersWithBaseURL(router, si, \"\")\n}\n\n// Registers handlers, and prepends BaseURL to the paths, so that the paths\n// can be served under a prefix.\nfunc RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {\n\t// ...\n\n\trouter.GET(baseURL+\"/ping\", wrapper.GetPing)\n\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/echo/api/impl.go):\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/labstack/echo/v4\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(ctx echo.Context) error {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\treturn ctx.JSON(http.StatusOK, resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/echo/api\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\te := echo.New()\n\n\tapi.RegisterHandlers(e, server)\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(e.Start(\"0.0.0.0:8080\"))\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### Fiber server\n\u003ca name=\"impl-fiber\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(c *fiber.Ctx) error\n}\n\n// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.\nfunc RegisterHandlers(router fiber.Router, si ServerInterface) {\n\tRegisterHandlersWithOptions(router, si, FiberServerOptions{})\n}\n\n// RegisterHandlersWithOptions creates http.Handler with additional options\nfunc RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) {\n\t// ...\n\n\trouter.Get(options.BaseURL+\"/ping\", wrapper.GetPing)\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/fiber/api/impl.go):\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ensure that we've conformed to the `ServerInterface` with a compile-time check\nvar _ ServerInterface = (*Server)(nil)\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(ctx *fiber.Ctx) error {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\treturn ctx.\n\t\tStatus(http.StatusOK).\n\t\tJSON(resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/fiber/api\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\tapp := fiber.New()\n\n\tapi.RegisterHandlers(app, server)\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(app.Listen(\"0.0.0.0:8080\"))\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### Gin server\n\u003ca name=\"impl-gin\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(c *gin.Context)\n}\n\n// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.\nfunc RegisterHandlers(router gin.IRouter, si ServerInterface) {\n\tRegisterHandlersWithOptions(router, si, GinServerOptions{})\n}\n\n// RegisterHandlersWithOptions creates http.Handler with additional options\nfunc RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {\n\t// ...\n\n\trouter.GET(options.BaseURL+\"/ping\", wrapper.GetPing)\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/gorillamux/api/impl.go):\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(ctx *gin.Context) {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\tctx.JSON(http.StatusOK, resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/gin/api\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\tr := gin.Default()\n\n\tapi.RegisterHandlers(r, server)\n\n\t// And we serve HTTP until the world ends.\n\n\ts := \u0026http.Server{\n\t\tHandler: r,\n\t\tAddr:    \"0.0.0.0:8080\",\n\t}\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(s.ListenAndServe())\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### Iris server\n\u003ca name=\"impl-iris\"\u003e\u003c/a\u003e\n\nFor instance, let's take this straightforward specification:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Minimal ping API server\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\ncomponents:\n  schemas:\n    # base types\n    Pong:\n      type: object\n      required:\n        - ping\n      properties:\n        ping:\n          type: string\n          example: pong\n```\n\nThis then generates code such as:\n\n```go\n// Pong defines model for Pong.\ntype Pong struct {\n\tPing string `json:\"ping\"`\n}\n\n// ServerInterface represents all server handlers.\ntype ServerInterface interface {\n\n\t// (GET /ping)\n\tGetPing(ctx iris.Context)\n}\n\n// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.\nfunc RegisterHandlers(router *iris.Application, si ServerInterface) {\n\tRegisterHandlersWithOptions(router, si, IrisServerOptions{})\n}\n\n// RegisterHandlersWithOptions creates http.Handler with additional options\nfunc RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) {\n\t// ...\n\n\trouter.Get(options.BaseURL+\"/ping\", wrapper.GetPing)\n\n\trouter.Build()\n}\n```\n\nTo implement this HTTP server, we need to write the following code in our [`api/impl.go`](examples/minimal-server/gorillamux/api/impl.go):\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/kataras/iris/v12\"\n)\n\n// optional code omitted\n\ntype Server struct{}\n\nfunc NewServer() Server {\n\treturn Server{}\n}\n\n// (GET /ping)\nfunc (Server) GetPing(ctx iris.Context) {\n\tresp := Pong{\n\t\tPing: \"pong\",\n\t}\n\n\tctx.StatusCode(http.StatusOK)\n\t_ = ctx.JSON(resp)\n}\n```\n\nNow we've got our implementation, we can then write the following code to wire it up and get a running server:\n\n```go\nimport (\n\t\"log\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/iris/api\"\n\t\"github.com/kataras/iris/v12\"\n)\n\nfunc main() {\n\t// create a type that satisfies the `api.ServerInterface`, which contains an implementation of every operation from the generated code\n\tserver := api.NewServer()\n\n\ti := iris.Default()\n\n\tapi.RegisterHandlers(i, server)\n\n\t// And we serve HTTP until the world ends.\n\tlog.Fatal(i.Listen(\"0.0.0.0:8080\"))\n}\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n### Strict server\n\n`oapi-codegen` also supports generating a server that is much more strict with the contract that the implementer requires, and takes inspiration from server-side code generation for RPC servers.\n\nThis takes the boilerplate reduction from the non-strict servers and adds additional boilerplate reduction, allowing you to make the following changes to your function signatures:\n\n```diff\n-FindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams)\n+FindPets(ctx context.Context, request FindPetsRequestObject) (FindPetsResponseObject, error)\n```\n\nThis is the highest level of strictness that `oapi-codegen` supports right now, and it's a good idea to start with this if you want the most guardrails to simplify developing your APIs.\n\nThe strict server has support for:\n\n- multiple request/response media types and status codes on a given operation\n- first-class support for `multipart/form-data` and `application/x-www-form-urlencoded` requests\n- returning an [HTTP 500 Internal Server Error](https://http.cat/500), when an `error` is returned from a function\n- automagic (un)marshalling of request/responses, and setting `content-type` and HTTP status codes on responses\n- binding request values to a struct, a `multipart.Reader` or providing a `io.Reader`\n\nYou can see a little more detail of the generated code in the [\"What does it look like\"](#what-does-it-look-like-strict) section.\n\n\u003e [!NOTE]\n\u003e To configure the strict server generation, you must specify another server to be generated. For instance:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: api\ngenerate:\n  # NOTE another server must be added!\n  chi-server: true\n  strict-server: true\noutput: server.gen.go\n```\n\n\u003e [!NOTE]\n\u003e This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n## Generating API clients\n\nAs well as generating the server-side boilerplate, `oapi-codegen` can also generate API clients.\n\nThis aims to be an API client that can be used to interact with the methods of the API, and is perfectly suited for production usage.\n\nHowever, if you were looking for a slightly more SDK-style approach, or a mix of generated tests and/or documentation, this API client may not be for you, and you may want to look at alternate tooling.\n\nFor instance, given an `api.yaml`:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Generate models\npaths:\n  /client:\n    get:\n      operationId: getClient\n      responses:\n        200:\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/ClientType\"\n    put:\n      operationId: updateClient\n      responses:\n        400:\n          content:\n            application/json:\n              schema:\n                type: object\n                properties:\n                  code:\n                    type: string\n                required:\n                - code\ncomponents:\n  schemas:\n    ClientType:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n    # NOTE that this is not generated by default because it's not referenced. If you want it, you need to use the following YAML configuration:\n    #\n    # output-options:\n    #   skip-prune: true\n    Unreferenced:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n```\n\nAnd a `cfg.yaml`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: client\noutput: client.gen.go\ngenerate:\n  models: true\n  client: true\n```\n\nAnd a `generate.go`:\n\n```go\npackage client\n\n//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml\n```\n\nThis would then generate:\n\n```go\npackage client\n\n// ...\n\n// ClientType defines model for ClientType.\ntype ClientType struct {\n\tName string `json:\"name\"`\n}\n\n// ...\n\n// Client which conforms to the OpenAPI3 specification for this service.\ntype Client struct {\n\t// The endpoint of the server conforming to this interface, with scheme,\n\t// https://api.deepmap.com for example. This can contain a path relative\n\t// to the server, such as https://api.deepmap.com/dev-test, and all the\n\t// paths in the swagger spec will be appended to the server.\n\tServer string\n\n\t// Doer for performing requests, typically a *http.Client with any\n\t// customized settings, such as certificate chains.\n\tClient HttpRequestDoer\n\n\t// A list of callbacks for modifying requests which are generated before sending over\n\t// the network.\n\tRequestEditors []RequestEditorFn\n}\n\n// ...\n\n// The interface specification for the client above.\ntype ClientInterface interface {\n\t// GetClient request\n\tGetClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)\n\n\t// UpdateClient request\n\tUpdateClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)\n}\n\n// ...\n\n// ClientWithResponsesInterface is the interface specification for the client with responses above.\ntype ClientWithResponsesInterface interface {\n\t// GetClientWithResponse request\n\tGetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error)\n\n\t// UpdateClientWithResponse request\n\tUpdateClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*UpdateClientResponse, error)\n}\n\ntype GetClientResponse struct {\n\tBody         []byte\n\tHTTPResponse *http.Response\n\tJSON200      *ClientType\n}\n\n// ...\n```\n\nWith this generated client, it is then possible to construct and utilise the client, for instance:\n\n```go\npackage client_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/examples/client\"\n)\n\nfunc TestClient_canCall() {\n\t// custom HTTP client\n\thc := http.Client{}\n\n\t// with a raw http.Response\n\t{\n\t\tc, err := client.NewClient(\"http://localhost:1234\", client.WithHTTPClient(\u0026hc))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tresp, err := c.GetClient(context.TODO())\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tlog.Fatalf(\"Expected HTTP 200 but received %d\", resp.StatusCode)\n\t\t}\n\t}\n\n\t// or to get a struct with the parsed response body\n\t{\n\t\tc, err := client.NewClientWithResponses(\"http://localhost:1234\", client.WithHTTPClient(\u0026hc))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tresp, err := c.GetClientWithResponse(context.TODO())\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif resp.StatusCode() != http.StatusOK {\n\t\t\tlog.Fatalf(\"Expected HTTP 200 but received %d\", resp.StatusCode())\n\t\t}\n\n\t\tfmt.Printf(\"resp.JSON200: %v\\n\", resp.JSON200)\n\t}\n\n}\n```\n\n## Generating API models\n\nIf you're looking to only generate the models for interacting with a remote service, for instance if you need to hand-roll the API client for whatever reason, you can do this as-is.\n\n\u003e [!TIP]\n\u003e Try to define as much as possible within the `#/components/schemas` object, as `oapi-codegen` will generate all the types here.\n\u003e\n\u003e Although we can generate some types based on inline definitions in i.e. a path's response type, it isn't always possible to do this, or if it is generated, can be a little awkward to work with as it may be defined as an anonymous struct.\n\nFor instance, given an `api.yaml`:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Generate models\npaths:\n  /client:\n    get:\n      operationId: getClient\n      responses:\n        200:\n          content:\n            application/json:\n              schema:\n                # NOTE that Client is generated here, because it's within #/components/schemas\n                $ref: \"#/components/schemas/Client\"\n    put:\n      operationId: updateClient\n      responses:\n        400:\n          content:\n            application/json:\n              # NOTE that this anonymous object is /not/ generated because it's an anonymous, but would be generated if using `generate: client`\n              # See https://github.com/oapi-codegen/oapi-codegen/issues/1512\n              schema:\n                type: object\n                properties:\n                  code:\n                    type: string\n                required:\n                - code\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n    # NOTE that this is not generated by default because it's not referenced. If you want it, you need to use the following YAML configuration:\n    #\n    # output-options:\n    #   skip-prune: true\n    Unreferenced:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n```\n\nAnd a `cfg.yaml`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: onlymodels\noutput: only-models.gen.go\ngenerate:\n  models: true\n```\n\nAnd a `generate.go`:\n\n```go\npackage onlymodels\n\n//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml\n```\n\nThis would then generate:\n\n```go\npackage onlymodels\n\n// Client defines model for Client.\ntype Client struct {\n\tName string `json:\"name\"`\n}\n```\n\nIf you wish to also generate the `Unreferenced` type, you would need the following `cfg.yaml`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: onlymodels\noutput: only-models.gen.go\ngenerate:\n  models: true\noutput-options:\n  # NOTE that this is only required for the `Unreferenced` type\n  skip-prune: true\n```\n\nFor a complete example see [`examples/only-models`](examples/only-models).\n\n## Splitting large OpenAPI specs across multiple packages (aka \"Import Mapping\" or \"external references\")\n\u003ca name=import-mapping\u003e\u003c/a\u003e\n\nWhen you've got a large OpenAPI specification, you may find it useful to split the contents of the spec across multiple files, using external references, such as:\n\n```yaml\n      responses:\n        200:\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/User'\n```\n\nThis is supported by `oapi-codegen`, through the ability to perform \"Import Mapping\".\n\nFor instance, let's say that we have a large API, which has a user-facing API and an admin API, both of which use a common set of API models.\n\nIn this case, we may have an Admin API that looks like:\n\n```yaml\n# admin/api.yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Admin API\n  description: The admin-only portion of the API, which has its own separate OpenAPI spec\ntags:\n  - name: admin\n    description: Admin API endpoints\n  - name: user\n    description: API endpoint that pertains to user data\npaths:\n  /admin/user/{id}:\n    get:\n      tags:\n        - admin\n        - user\n      summary: Get a user's details\n      operationId: getUserById\n      parameters:\n        - name: id\n          in: path\n          required: true\n          schema:\n            type: string\n            format: uuid\n      responses:\n        200:\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '../common/api.yaml#/components/schemas/User'\n```\n\nThis references the common spec:\n\n```yaml\n# common/api.yaml\ncomponents:\n  schemas:\n    User:\n      type: object\n      additionalProperties: false\n      properties:\n        name:\n          type: string\n      required:\n        - name\n```\n\nSo how do we get `oapi-codegen` to generate our code?\n\n### Using a single package with multiple OpenAPI specs\n\n\u003ca name=import-mapping-self\u003e\u003c/a\u003e\n\n\u003e [!TIP]\n\u003e Since `oapi-codegen` v2.4.0, it is now possible to split large OpenAPI specifications into the same Go package, using the \"self\" mapping (denoted by a `-`) when using Import Mapping.\n\u003e\n\u003e This is an improvement on the previous model, which would require splitting files across multiple packages.\n\n\u003e [!NOTE]\n\u003e You still need to have multiple `go generate`s, and any other configuration files.\n\nTo get `oapi-codegen`'s single-package support working, we need multiple calls to `oapi-codegen`, one call per OpenAPI spec file:\n\n```sh\n$ go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg-api.yaml ../admin/api.yaml\n$ go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg-user.yaml ../common/api.yaml\n```\n\nThis therefore means that we need multiple configuration files, such as `cfg-api.yaml`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: samepackage\noutput: server.gen.go\ngenerate:\n  models: true\n  chi-server: true\n  strict-server: true\noutput-options:\n  # to make sure that all types are generated\n  skip-prune: true\nimport-mapping:\n  user.yaml: \"-\"\n```\n\nAnd then our `cfg-user.yaml`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: samepackage\noutput: user.gen.go\ngenerate:\n  models: true\noutput-options:\n  # to make sure that all types are generated\n  skip-prune: true\n```\n\nFrom here, `oapi-codegen` will generate multiple Go files, all within the same package, which can be used to break down your large OpenAPI specifications, and generate only the subsets of code needed for each part of the spec.\n\nCheck out [the import-mapping/samepackage example](examples/import-mapping/samepackage) for the full code.\n\n### Using multiple packages, with one OpenAPI spec per package\n\nTo get `oapi-codegen`'s multi-package support working, we need to set up our directory structure:\n\n```\n├── admin\n│   ├── cfg.yaml\n│   └── generate.go\n└── common\n    ├── cfg.yaml\n    └── generate.go\n```\n\nWe could start with our configuration file for our admin API spec:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\n# admin/cfg.yaml\npackage: admin\noutput: server.gen.go\ngenerate:\n  models: true\n  chi-server: true\noutput-options:\n  # to make sure that all types are generated\n  skip-prune: true\n# NOTE that this won't work, as it's missing `import-mapping`\n```\n\nIf we were to run `oapi-codegen`, this will fail with the following error\n\n```\nerror generating code: error creating operation definitions: error generating response definitions: error generating request body definition: error turning reference (../common/api.yaml#/components/schemas/User) into a Go type: unrecognized external reference '../common/api.yaml'; please provide the known import for this reference using option --import-mapping\n```\n\nThis is because `oapi-codegen` requires the `import-mapping`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: admin\noutput: server.gen.go\ngenerate:\n  models: true\n  chi-server: true\noutput-options:\n  # to make sure that all types are generated\n  skip-prune: true\nimport-mapping:\n  # for a given file/URL that is $ref'd, point `oapi-codegen` to the Go package that this spec is generated into, to perform Go package imports\n  ../common/api.yaml: github.com/oapi-codegen/oapi-codegen/v2/examples/import-mapping/common\n```\n\nThis will then generate the following code:\n\n```go\npackage admin\n\nimport (\n\t// ...\n\texternalRef0 \"github.com/oapi-codegen/oapi-codegen/v2/examples/import-mapping/common\"\n)\n\n// User defines model for User.\ntype User = externalRef0.User\n```\n\nIf you don't want to do this, an alternate option is to [use a single package, with multiple OpenAPI spec files for that given package](#import-mapping-self) or to [bundle your multiple OpenAPI files](https://www.jvt.me/posts/2022/02/10/bundle-openapi/) into a single spec.\n\nCheck out [the import-mapping/multiplepackages example](examples/import-mapping/multiplepackages/) for the full code.\n\n## Modifying the input OpenAPI Specification (with OpenAPI Overlay)\n\nPrior to `oapi-codegen` v2.4.0, users wishing to override specific configuration, for instance taking advantage of extensions such as `x-go-type`  would need to modify the OpenAPI specification they are using.\n\nIn a lot of cases, this OpenAPI specification would be produced by a different team to the consumers (or even a different company) and so asking them to make changes like this were unreasonable.\n\nThis would lead to the API consumers needing to vendor the specification from the producer (which is [our recommendation anyway](#https-paths)) and then make any number of local changes to the specification to make it generate code that looks reasonable.\n\nHowever, in the case that a consumer would update their specification, they would likely end up with a number of merge conflicts.\n\nNow, as of `oapi-codegen` v2.4.0, it is now possible to make changes to the input OpenAPI specification _without needing to modify it directly_.\n\nThis takes advantage of the [OpenAPI Overlay specification](https://github.com/OAI/Overlay-Specification), which is a stable specification.\n\n\u003e [!CAUTION]\n\u003e Beware! Here (may) be dragons.\n\u003e\n\u003e The Overlay specification requires the use of JSON Path, which some users may find difficult to write and/or maintain.\n\u003e\n\u003e We still heavily recommend using Overlay functionality, but would like users to be aware of this.\n\u003e\n\u003e There is a [proposed modification to the specification](https://github.com/OAI/Overlay-Specification/pull/32) which would relax the need for JSON Path as the targeting mechanism.\n\nFor instance, let's say that we have the following OpenAPI specification, which provides insight into an internal endpoint that we should not be generating any code for (denoted by `x-internal`):\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: \"Example to indicate how to use the OpenAPI Overlay specification (https://github.com/OAI/Overlay-Specification)\"\npaths:\n  /ping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pong'\n    delete:\n      x-internal: true\n      responses:\n        '202':\n          content: {}\n```\n\nIf we were to run `oapi-codegen` with out-of-the-box functionality, this would then lead to the DELETE endpoint being generated, which we don't want.\n\nInstead, we can define the following `overlay.yaml`:\n\n\n```yaml\noverlay: 1.0.0\ninfo:\n  title: Overlay\n  version: 0.0.0\nactions:\n- target: \"$\"\n  description: Perform a structural overlay, which can be more readable, as it's clear what the shape of the document is\n  update:\n    info:\n      x-overlay-applied: structured-overlay\n    paths:\n      /ping:\n        get:\n          responses:\n            '200':\n              description: Perform a ping request\n- target: $.paths.*[?(@.x-internal)]\n  description: Remove internal endpoints (noted by x-internal)\n  remove: true\n- target: $.paths.*.*[?(@.x-internal)]\n  description: Remove internal endpoints (noted by x-internal)\n  remove: true\n```\n\nAnd our configuration file for `oapi-codegen`:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\npackage: api\noutput: ping.gen.go\ngenerate:\n  models: true\n  gorilla-server: true\n  embedded-spec: true\noutput-options:\n  overlay:\n    path: overlay.yaml\n```\n\nThis then completely removes the DELETE endpoint _before_ we even start to parse the specification in `oapi-codegen`, so it's as if your specification was provided without that endpoint.\n\nAdditionally, we can override other pieces of metadata, such as the description for operations.\n\nCheck out [the overlay example](examples/overlay/) for the full code, and some more complex examples.\n\n## Generating Nullable types\n\nIt's possible that you want to be able to determine whether a field isn't sent, is sent as `null` or has a value.\n\nFor instance, if you had the following OpenAPI property:\n\n```yaml\nS:\n  type: object\n  properties:\n    Field:\n      type: string\n      nullable: true\n    required: []\n```\n\nThe default behaviour in `oapi-codegen` is to generate:\n\n```go\ntype S struct {\n\tField *string `json:\"field,omitempty\"`\n}\n```\n\nHowever, you lose the ability to understand the three cases, as there's no way to distinguish two of the types from each other:\n\n- is this field not sent? (Can be checked with `S.Field == nil`)\n- is this field `null`? (Can be checked with `S.Field == nil`)\n- does this field have a value? (`S.Field != nil \u0026\u0026 *S.Field == \"123\"`)\n\nAs of `oapi-codegen` [v2.1.0](https://github.com/oapi-codegen/oapi-codegen/releases/tag/v2.1.0) it is now possible to represent this with the `nullable.Nullable` type from [our new library, oapi-codegen/nullable](https://github.com/oapi-codegen/nullable).\n\nIf you configure your generator's Output Options to opt-in to this behaviour, as so:\n\n```yaml\noutput-options:\n  nullable-type: true\n```\n\nYou will now receive the following output:\n\n```go\ntype S struct {\n    // note that there's no pointer here, just `omitempty`\n    Field nullable.Nullable[string] `json:\"field,omitempty\"`\n}\n```\n\n## OpenAPI extensions\n\nAs well as the core OpenAPI support, we also support the following OpenAPI extensions, as denoted by the [OpenAPI Specification Extensions](https://spec.openapis.org/oas/v3.0.3#specification-extensions).\n\n\u003ctable\u003e\n\n\u003ctr\u003e\n\u003cth\u003e\nExtension\n\u003c/th\u003e\n\u003cth\u003e\nDescription\n\u003c/th\u003e\n\u003cth\u003e\nExample usage\n\u003c/th\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-go-type` \u003cbr\u003e\n`x-go-type-import`\n\n\u003c/td\u003e\n\u003ctd\u003e\nOverride the generated type definition (and optionally, add an import from another package)\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nUsing the `x-go-type` (and optionally, `x-go-type-import` when you need to import another package) allows overriding the type that `oapi-codegen` determined the generated type should be.\n\nWe can see this at play with the following schemas:\n\n```yaml\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n          # this is a bit of a contrived example, as you could instead use\n          # `format: uuid` but it explains how you'd do this when there may be\n          # a clash, for instance if you already had a `uuid` package that was\n          # being imported, or ...\n          x-go-type: googleuuid.UUID\n          x-go-type-import:\n            path: github.com/google/uuid\n            name: googleuuid\n        id:\n          type: number\n          # ... this is also a bit of a contrived example, as you could use\n          # `type: integer` but in the case that you know better than what\n          # oapi-codegen is generating, like so:\n          x-go-type: int64\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId   *int64          `json:\"id,omitempty\"`\n\tName googleuuid.UUID `json:\"name\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xgotype/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-go-type-skip-optional-pointer`\n\n\u003c/td\u003e\n\u003ctd\u003e\nDo not add a pointer type for optional fields in structs\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\n\u003e [!TIP]\n\u003e If you prefer this behaviour, and prefer to not have to annotate your whole OpenAPI spec for this behaviour, you can use `output-options.prefer-skip-optional-pointer=true` to default this behaviour for all fields.\n\u003e\n\u003e It is then possible to override this on a per-type/per-field basis where necessary.\n\nBy default, `oapi-codegen` will generate a pointer for optional fields.\n\nUsing the `x-go-type-skip-optional-pointer` extension allows omitting that pointer.\n\nWe can see this at play with the following schemas:\n\n```yaml\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n          x-go-type-skip-optional-pointer: true\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId   float32 `json:\"id,omitempty\"`\n\tName string  `json:\"name\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xgotypeskipoptionalpointer/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-go-name`\n\n\u003c/td\u003e\n\u003ctd\u003e\nOverride the generated name of a field or a type\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nBy default, `oapi-codegen` will attempt to generate the name of fields and types in as best a way it can.\n\nHowever, sometimes, the name doesn't quite fit what your codebase standards are, or the intent of the field, so you can override it with `x-go-name`.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-go-name\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      # can be used on a type\n      x-go-name: ClientRenamedByExtension\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n          # or on a field\n          x-go-name: AccountIdentifier\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientRenamedByExtension defines model for ClientWithExtension.\ntype ClientRenamedByExtension struct {\n\tAccountIdentifier *float32 `json:\"id,omitempty\"`\n\tName              string   `json:\"name\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xgoname/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-go-type-name`\n\n\u003c/td\u003e\n\u003ctd\u003e\nOverride the generated name of a type\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\n\u003e [!NOTE]\n\u003e Notice that this is subtly different to the `x-go-name`, which also applies to _fields_ within `struct`s.\n\nBy default, `oapi-codegen` will attempt to generate the name of types in as best a way it can.\n\nHowever, sometimes, the name doesn't quite fit what your codebase standards are, or the intent of the field, so you can override it with `x-go-name`.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-go-type-name\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      x-go-type-name: ClientRenamedByExtension\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n          # NOTE attempting a `x-go-type-name` here is a no-op, as we're not producing a _type_ only a _field_\n          x-go-type-name: ThisWillNotBeUsed\n```\n\nFrom here, we now get two different models and a type alias:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension = ClientRenamedByExtension\n\n// ClientRenamedByExtension defines model for .\ntype ClientRenamedByExtension struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xgotypename/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-omitempty`\n\n\u003c/td\u003e\n\u003ctd\u003e\nForce the presence of the JSON tag `omitempty` on a field\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nIn a case that you may want to add the JSON struct tag `omitempty` to types that don't have one generated by default - for instance a required field - you can use the `x-omitempty` extension.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-omitempty\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n          # for some reason, you may want this behaviour, even though it's a required field\n          x-omitempty: true\n        id:\n          type: number\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name,omitempty\"`\n}\n```\n\nNotice that the `ComplexField` is still generated in full, but the type will then be ignored with JSON marshalling.\n\nYou can see this in more detail in [the example code](examples/extensions/xgojsonignore/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-go-json-ignore`\n\n\u003c/td\u003e\n\u003ctd\u003e\nWhen (un)marshaling JSON, ignore field(s)\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nBy default, `oapi-codegen` will generate `json:\"...\"` struct tags for all fields in a struct, so JSON (un)marshaling works.\n\nHowever, sometimes, you want to omit fields, which can be done with the `x-go-json-ignore` extension.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-go-json-ignore\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        complexField:\n          type: object\n          properties:\n            name:\n              type: string\n            accountName:\n              type: string\n          # ...\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        complexField:\n          type: object\n          properties:\n            name:\n              type: string\n            accountName:\n              type: string\n          # ...\n          x-go-json-ignore: true\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tComplexField *struct {\n\t\tAccountName *string `json:\"accountName,omitempty\"`\n\t\tName        *string `json:\"name,omitempty\"`\n\t} `json:\"complexField,omitempty\"`\n\tName string `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tComplexField *struct {\n\t\tAccountName *string `json:\"accountName,omitempty\"`\n\t\tName        *string `json:\"name,omitempty\"`\n\t} `json:\"-\"`\n\tName string `json:\"name\"`\n}\n```\n\nNotice that the `ComplexField` is still generated in full, but the type will then be ignored with JSON marshalling.\n\nYou can see this in more detail in [the example code](examples/extensions/xgojsonignore/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-oapi-codegen-extra-tags`\n\n\u003c/td\u003e\n\u003ctd\u003e\nGenerate arbitrary struct tags to fields\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nIf you're making use of a field's struct tags to i.e. apply validation, decide whether something should be logged, etc, you can use `x-oapi-codegen-extra-tags` to set additional tags for your generated types.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-oapi-codegen-extra-tags\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n        - id\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n        - id\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n          x-oapi-codegen-extra-tags:\n            validate: \"required,min=1,max=256\"\n            safe-to-log: \"true\"\n            gorm: primarykey\n```\n\nFrom here, we now get two different models:\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   float32 `json:\"id\"`\n\tName string  `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId   float32 `gorm:\"primarykey\" json:\"id\" safe-to-log:\"true\" validate:\"required,min=1,max=256\"`\n\tName string  `json:\"name\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xoapicodegenextratags/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-enum-varnames` / `x-enumNames`\n\n\u003c/td\u003e\n\u003ctd\u003e\nOverride generated variable names for enum constants\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nWhen consuming an enum value from an external system, the name may not produce a nice variable name. Using the `x-enum-varnames` extension allows overriding the name of the generated variable names.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-enumNames and x-enum-varnames\ncomponents:\n  schemas:\n    ClientType:\n      type: string\n      enum:\n        - ACT\n        - EXP\n    ClientTypeWithNamesExtension:\n      type: string\n      enum:\n        - ACT\n        - EXP\n      x-enumNames:\n        - Active\n        - Expired\n    ClientTypeWithVarNamesExtension:\n      type: string\n      enum:\n        - ACT\n        - EXP\n      x-enum-varnames:\n        - Active\n        - Expired\n```\n\nFrom here, we now get two different forms of the same enum definition.\n\n```go\n// Defines values for ClientType.\nconst (\n\tACT ClientType = \"ACT\"\n\tEXP ClientType = \"EXP\"\n)\n\n// ClientType defines model for ClientType.\ntype ClientType string\n\n// Defines values for ClientTypeWithExtension.\nconst (\n\tActive  ClientTypeWithExtension = \"ACT\"\n\tExpired ClientTypeWithExtension = \"EXP\"\n)\n\n// ClientTypeWithExtension defines model for ClientTypeWithExtension.\ntype ClientTypeWithExtension string\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xenumvarnames/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-deprecated-reason`\n\n\u003c/td\u003e\n\u003ctd\u003e\nAdd a GoDoc deprecation warning to a type\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nWhen an OpenAPI type is deprecated, a deprecation warning can be added in the GoDoc using `x-deprecated-reason`.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-deprecated-reason\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n          deprecated: true\n          x-deprecated-reason: Don't use because reasons\n        id:\n          type: number\n          # NOTE that this doesn't generate, as no `deprecated: true` is set\n          x-deprecated-reason: NOTE you shouldn't see this, as you've not deprecated this field\n```\n\nFrom here, we now get two different forms of the same enum definition.\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tId   *float32 `json:\"id,omitempty\"`\n\tName string   `json:\"name\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId *float32 `json:\"id,omitempty\"`\n\t// Deprecated: Don't use because reasons\n\tName string `json:\"name\"`\n}\n```\n\nNotice that because we've not set `deprecated: true` to the `name` field, it doesn't generate a deprecation warning.\n\nYou can see this in more detail in [the example code](examples/extensions/xdeprecatedreason/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-order`\n\n\u003c/td\u003e\n\u003ctd\u003e\nExplicitly order struct fields\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\nWhether you like certain fields being ordered before others, or you want to perform more efficient packing of your structs, the `x-order` extension is here for you.\n\nNote that `x-order` is 1-indexed - `x-order: 0` is not a valid value.\n\nWhen an OpenAPI type is deprecated, a deprecation warning can be added in the GoDoc using `x-deprecated-reason`.\n\nWe can see this at play with the following schemas:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-order\ncomponents:\n  schemas:\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        a_name:\n          type: string\n        id:\n          type: number\n    ClientWithExtension:\n      type: object\n      required:\n        - name\n      properties:\n        a_name:\n          type: string\n          x-order: 2\n        id:\n          type: number\n          x-order: 1\n```\n\nFrom here, we now get two different forms of the same type definition.\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tAName *string  `json:\"a_name,omitempty\"`\n\tId    *float32 `json:\"id,omitempty\"`\n}\n\n// ClientWithExtension defines model for ClientWithExtension.\ntype ClientWithExtension struct {\n\tId    *float32 `json:\"id,omitempty\"`\n\tAName *string  `json:\"a_name,omitempty\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xorder/).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n`x-oapi-codegen-only-honour-go-name`\n\n\u003c/td\u003e\n\u003ctd\u003e\nOnly honour the `x-go-name` when generating field names\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\n\n\u003e [!WARNING]\n\u003e Using this option may lead to cases where `oapi-codegen`'s rewriting of field names to prevent clashes with other types, or to prevent including characters that may not be valid Go field names.\n\nIn some cases, you may not want use the inbuilt options for converting an OpenAPI field name to a Go field name, such as the `name-normalizer: \"ToCamelCaseWithInitialisms\"`, and instead trust the name that you've defined for the type better.\n\nIn this case, you can use `x-oapi-codegen-only-honour-go-name` to enforce this, alongside specifying the `allow-unexported-struct-field-names` compatibility option.\n\nThis allows you to take a spec such as:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: x-oapi-codegen-only-honour-go-name\ncomponents:\n  schemas:\n    TypeWithUnexportedField:\n      description: A struct will be output where one of the fields is not exported\n      properties:\n        name:\n          type: string\n        id:\n          type: string\n          # NOTE that there is an explicit usage of a lowercase character\n          x-go-name: accountIdentifier\n          x-oapi-codegen-extra-tags:\n            json: \"-\"\n          x-oapi-codegen-only-honour-go-name: true\n```\n\nAnd we'll generate:\n\n```go\n// TypeWithUnexportedField A struct will be output where one of the fields is not exported\ntype TypeWithUnexportedField struct {\n\taccountIdentifier *string `json:\"-\"`\n\tName              *string `json:\"name,omitempty\"`\n}\n```\n\nYou can see this in more detail in [the example code](examples/extensions/xoapicodegenonlyhonourgoname).\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003c/table\u003e\n\n## Request/response validation middleware\n\nThe generated code that `oapi-codegen` produces has some validation for some incoming data, such as checking for required headers, and when using the [strict server](#strict-server) you get some more validation around the correct usage of the response types.\n\nHowever, this leaves a lot of validation that needs to be done, which can be tedious to hand-write this logic, especially for large or complex OpenAPI specifications.\n\nTo simplify this, we use a middleware, which provides the request validation. The middleware you want to use depends on the server you're using:\n\n\u003ctable\u003e\n\n\u003ctr\u003e\n\u003cth\u003e\nServer\n\u003c/th\u003e\n\u003cth\u003e\nMiddleware library\n\u003c/th\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Chi](https://github.com/go-chi/chi)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[nethttp-middleware](https://github.com/oapi-codegen/nethttp-middleware)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Echo](https://github.com/labstack/echo)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[echo-middleware](https://github.com/oapi-codegen/echo-middleware)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Fiber](https://github.com/gofiber/fiber)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[fiber-middleware](https://github.com/oapi-codegen/fiber-middleware)\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Gin](https://github.com/gin-gonic/gin)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[gin-middleware](https://github.com/oapi-codegen/gin-middleware)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[gorilla/mux](https://github.com/gorilla/mux)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[nethttp-middleware](https://github.com/oapi-codegen/nethttp-middleware)\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Iris](https://github.com/kataras/iris)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[iris-middleware](https://github.com/oapi-codegen/iris-middleware)\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\n[1.22+ `net/http`](https://pkg.go.dev/net/http)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[nethttp-middleware](https://github.com/oapi-codegen/nethttp-middleware)\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\n\nAny other server (which conforms to `net/http`)\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n[nethttp-middleware](https://github.com/oapi-codegen/nethttp-middleware)\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003c/table\u003e\n\n\u003e [!NOTE]\n\u003e It is [not currently possible](https://github.com/oapi-codegen/oapi-codegen/issues/1038) to validate the HTTP response with a middleware.\n\n\u003e [!NOTE]\n\u003e We're also [exploring](https://github.com/oapi-codegen/exp/issues/1) the use of [libopenapi-validator](https://github.com/pb33f/libopenapi-validator/) for request/response validation middleware\n\n## Implementing security\n\nIf you're using a specification with [Security Schemes](https://spec.openapis.org/oas/v3.0.3#security-scheme-object) and [Security Requirements](https://spec.openapis.org/oas/v3.0.3#security-requirement-object), you'll want to authenticate and authorize requests.\n\n### On the server\n\n\u003e [!NOTE]\n\u003e Out-of-the-box, the server-side code generated by `oapi-codegen` does not provide security validation.\n\u003e\n\u003e To perform authentication, you will need to use the [validation middleware](#request-response-validation-middleware).\n\u003e\n\u003e In the future, we plan to [implement server-side validation in the generated code](https://github.com/oapi-codegen/oapi-codegen/issues/1524)\n\nTo see how this can work, check out the [authenticated API example](examples/authenticated-api/echo).\n\n### On the client\n\nWith a generated client, you'll want to use the client's generated `WithRequestEditorFn` function to pass in a given request editor `RequestEditorFn`.\n\nFor instance:\n\n```go\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/oapi-codegen/oapi-codegen/v2/pkg/securityprovider\"\n)\n\nfunc main() {\n\tbasicAuth, err := securityprovider.NewSecurityProviderBasicAuth(\"my_user\", \"my_pass\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tclient, err := NewClient(\"https://....\", WithRequestEditorFn(basicAuth.Intercept))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tresp, err := client.GetClient(context.TODO())\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"resp.StatusCode: %v\\n\", resp.StatusCode)\n}\n```\n\nNotice that we're using a pre-built provider from the [`pkg/securityprovider` package](https://pkg.go.dev/github.com/oapi-codegen/oapi-codegen/v2/pkg/securityprovider), which has some inbuilt support for other types of authentication, too.\n\n## Custom code generation\n\nIt is possible to extend the inbuilt code generation from `oapi-codegen` using Go's `text/template`s.\n\nYou can specify, through your configuration file, the `output-options.user-templates` setting to override the inbuilt templates and use a user-defined template.\n\n\u003e [!NOTE]\n\u003e Filenames given to the `user-templates` configuration must **exactly** match the filename that `oapi-codegen` is looking for\n\n### Local paths\n\nWithin your configuration file, you can specify relative or absolute paths to a file to reference for the template, such as:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\n# ...\noutput-options:\n  user-templates:\n    client-with-responses.tmpl: ./custom-template.tmpl\n    additional-properties.tmpl: /tmp/foo.bar\n    typedef.tmpl: no-prefix.tmpl\n```\n\n\u003e [!WARNING]\n\u003e We do not interpolate `~` or `$HOME` (or other environment variables) in paths given\n\n### HTTPS paths\n\nIt is also possible to use HTTPS URLs.\n\n\u003e [!WARNING]\n\u003e Although possible, this does lead to `oapi-codegen` executions not necessarily being reproducible. It's recommended to vendor (copy) the OpenAPI spec into your codebase and reference it locally\n\u003e\n\u003e See [this blog post](https://www.jvt.me/posts/2024/04/27/github-actions-update-file/) for an example of how to use GitHub Actions to manage the updates of files across repos\n\u003e\n\u003e This will be disabled by default (but possible to turn back on via configuration) [in the future](https://github.com/oapi-codegen/oapi-codegen/issues/1564)\n\nTo use it, you can use the following configuration:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\n# ...\noutput-options:\n  user-templates:\n    # The following are referencing a version of the default client-with-responses.tmpl file, but loaded in through GitHub's raw.githubusercontent.com. The general form to use raw.githubusercontent.com is as follows https://raw.githubusercontent.com/\u003cusername\u003e/\u003cproject\u003e/\u003ccommitish\u003e/path/to/template/template.tmpl\n\n    # Alternatively using raw.githubusercontent.com with a hash\n    client-with-responses.tmpl: https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/ad5eada4f3ccc28a88477cef62ea21c17fc8aa01/pkg/codegen/templates/client-with-responses.tmpl\n    # Alternatively using raw.githubusercontent.com with a tag\n    client-with-responses.tmpl: https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/v2.1.0/pkg/codegen/templates/client-with-responses.tmpl\n    # Alternatively using raw.githubusercontent.com with a branch\n    client-with-responses.tmpl: https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/master/pkg/codegen/templates/client-with-responses.tmpl\n```\n\n\u003e [!WARNING]\n\u003e If using URLs that pull locations from a Git repo, such as `raw.githubusercontent.com`, it is strongly encouraged to use a tag or a raw commit hash instead of a branch like `main`. Tracking a branch can lead to unexpected API drift, and loss of the ability to reproduce a build.\n\n### Inline template\n\nIt's also possible to set the templates inline in the configuration file:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\n# ...\noutput-options:\n  user-templates:\n    # NOTE the use of the `|` (pipe symbol) here to denote that this is a\n    # multi-line statement that should preserve newlines. More reading:\n    # https://stackoverflow.com/a/18708156/2257038 and\n    # https://stackoverflow.com/a/15365296/2257038\n    client-with-responses.tmpl: |\n        // ClientWithResponses builds on ClientInterface to offer response payloads\n        type ClientWithResponses struct {\n            ClientInterface\n        }\n        ...\n```\n\n### Using the Go package\n\nAlternatively, you are able to use the underlying code generation as a package, which [will be documented in the future](https://github.com/oapi-codegen/oapi-codegen/issues/1487).\n\n## Additional Properties (`additionalProperties`)\n\n[OpenAPI Schemas](https://spec.openapis.org/oas/v3.0.3.html#schema-object) implicitly accept `additionalProperties`, meaning that any fields provided, but not explicitly defined via properties on the schema are accepted as input, and propagated. When unspecified, OpenAPI defines that the `additionalProperties` field is assumed to be `true`.\n\nFor simplicity, and to remove a fair bit of duplication and boilerplate, `oapi-codegen` decides to ignore the implicit `additionalProperties: true`, and instead requires you to specify the `additionalProperties` key to generate the boilerplate.\n\n\u003e [!NOTE]\n\u003e In the future [this will be possible](https://github.com/oapi-codegen/oapi-codegen/issues/1514) to disable this functionality, and honour the implicit `additionalProperties: true`\n\nBelow you can see some examples of how `additionalProperties` affects the generated code.\n\n### Implicit `additionalProperties: true` / no `additionalProperties` set\n\n```yaml\ncomponents:\n  schemas:\n    Thing:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n      # implicit additionalProperties: true\n```\n\nWill generate:\n\n```go\n// Thing defines model for Thing.\ntype Thing struct {\n\tId int `json:\"id\"`\n}\n\n// with no generated boilerplate nor the `AdditionalProperties` field\n```\n\n### Explicit `additionalProperties: true`\n\n```yaml\ncomponents:\n  schemas:\n    Thing:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n      # explicit true\n      additionalProperties: true\n```\n\nWill generate:\n\n```go\n// Thing defines model for Thing.\ntype Thing struct {\n\tId                   int                    `json:\"id\"`\n\tAdditionalProperties map[string]interface{} `json:\"-\"`\n}\n\n// with generated boilerplate below\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003eBoilerplate\u003c/summary\u003e\n\n```go\n\n// Getter for additional properties for Thing. Returns the specified\n// element and whether it was found\nfunc (a Thing) Get(fieldName string) (value interface{}, found bool) {\n\tif a.AdditionalProperties != nil {\n\t\tvalue, found = a.AdditionalProperties[fieldName]\n\t}\n\treturn\n}\n\n// Setter for additional properties for Thing\nfunc (a *Thing) Set(fieldName string, value interface{}) {\n\tif a.AdditionalProperties == nil {\n\t\ta.AdditionalProperties = make(map[string]interface{})\n\t}\n\ta.AdditionalProperties[fieldName] = value\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a *Thing) UnmarshalJSON(b []byte) error {\n\tobject := make(map[string]json.RawMessage)\n\terr := json.Unmarshal(b, \u0026object)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif raw, found := object[\"id\"]; found {\n\t\terr = json.Unmarshal(raw, \u0026a.Id)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading 'id': %w\", err)\n\t\t}\n\t\tdelete(object, \"id\")\n\t}\n\n\tif len(object) != 0 {\n\t\ta.AdditionalProperties = make(map[string]interface{})\n\t\tfor fieldName, fieldBuf := range object {\n\t\t\tvar fieldVal interface{}\n\t\t\terr := json.Unmarshal(fieldBuf, \u0026fieldVal)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error unmarshaling field %s: %w\", fieldName, err)\n\t\t\t}\n\t\t\ta.AdditionalProperties[fieldName] = fieldVal\n\t\t}\n\t}\n\treturn nil\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a Thing) MarshalJSON() ([]byte, error) {\n\tvar err error\n\tobject := make(map[string]json.RawMessage)\n\n\tobject[\"id\"], err = json.Marshal(a.Id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling 'id': %w\", err)\n\t}\n\n\tfor fieldName, field := range a.AdditionalProperties {\n\t\tobject[fieldName], err = json.Marshal(field)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error marshaling '%s': %w\", fieldName, err)\n\t\t}\n\t}\n\treturn json.Marshal(object)\n}\n```\n\n\u003c/details\u003e\n\n\n### `additionalProperties` as `integer`s\n\n```yaml\ncomponents:\n  schemas:\n    Thing:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n      # simple type\n      additionalProperties:\n        type: integer\n```\n\nWill generate:\n\n```go\n// Thing defines model for Thing.\ntype Thing struct {\n\tId                   int            `json:\"id\"`\n\tAdditionalProperties map[string]int `json:\"-\"`\n}\n\n// with generated boilerplate below\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003eBoilerplate\u003c/summary\u003e\n\n```go\n// Getter for additional properties for Thing. Returns the specified\n// element and whether it was found\nfunc (a Thing) Get(fieldName string) (value int, found bool) {\n\tif a.AdditionalProperties != nil {\n\t\tvalue, found = a.AdditionalProperties[fieldName]\n\t}\n\treturn\n}\n\n// Setter for additional properties for Thing\nfunc (a *Thing) Set(fieldName string, value int) {\n\tif a.AdditionalProperties == nil {\n\t\ta.AdditionalProperties = make(map[string]int)\n\t}\n\ta.AdditionalProperties[fieldName] = value\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a *Thing) UnmarshalJSON(b []byte) error {\n\tobject := make(map[string]json.RawMessage)\n\terr := json.Unmarshal(b, \u0026object)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif raw, found := object[\"id\"]; found {\n\t\terr = json.Unmarshal(raw, \u0026a.Id)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading 'id': %w\", err)\n\t\t}\n\t\tdelete(object, \"id\")\n\t}\n\n\tif len(object) != 0 {\n\t\ta.AdditionalProperties = make(map[string]int)\n\t\tfor fieldName, fieldBuf := range object {\n\t\t\tvar fieldVal int\n\t\t\terr := json.Unmarshal(fieldBuf, \u0026fieldVal)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error unmarshaling field %s: %w\", fieldName, err)\n\t\t\t}\n\t\t\ta.AdditionalProperties[fieldName] = fieldVal\n\t\t}\n\t}\n\treturn nil\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a Thing) MarshalJSON() ([]byte, error) {\n\tvar err error\n\tobject := make(map[string]json.RawMessage)\n\n\tobject[\"id\"], err = json.Marshal(a.Id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling 'id': %w\", err)\n\t}\n\n\tfor fieldName, field := range a.AdditionalProperties {\n\t\tobject[fieldName], err = json.Marshal(field)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error marshaling '%s': %w\", fieldName, err)\n\t\t}\n\t}\n\treturn json.Marshal(object)\n}\n```\n\n\u003c/details\u003e\n\n### `additionalProperties` with an object\n\n```yaml\ncomponents:\n  schemas:\n    Thing:\n      type: object\n      required:\n        - id\n      properties:\n        id:\n          type: integer\n      # object\n      additionalProperties:\n        type: object\n        properties:\n          foo:\n            type: string\n```\n\nWill generate:\n\n```go\n// Thing defines model for Thing.\ntype Thing struct {\n\tId                   int `json:\"id\"`\n\tAdditionalProperties map[string]struct {\n\t\tFoo *string `json:\"foo,omitempty\"`\n\t} `json:\"-\"`\n}\n\n// with generated boilerplate below\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003eBoilerplate\u003c/summary\u003e\n\n```go\n// Getter for additional properties for Thing. Returns the specified\n// element and whether it was found\nfunc (a Thing) Get(fieldName string) (value struct {\n\tFoo *string `json:\"foo,omitempty\"`\n}, found bool) {\n\tif a.AdditionalProperties != nil {\n\t\tvalue, found = a.AdditionalProperties[fieldName]\n\t}\n\treturn\n}\n\n// Setter for additional properties for Thing\nfunc (a *Thing) Set(fieldName string, value struct {\n\tFoo *string `json:\"foo,omitempty\"`\n}) {\n\tif a.AdditionalProperties == nil {\n\t\ta.AdditionalProperties = make(map[string]struct {\n\t\t\tFoo *string `json:\"foo,omitempty\"`\n\t\t})\n\t}\n\ta.AdditionalProperties[fieldName] = value\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a *Thing) UnmarshalJSON(b []byte) error {\n\tobject := make(map[string]json.RawMessage)\n\terr := json.Unmarshal(b, \u0026object)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif raw, found := object[\"id\"]; found {\n\t\terr = json.Unmarshal(raw, \u0026a.Id)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading 'id': %w\", err)\n\t\t}\n\t\tdelete(object, \"id\")\n\t}\n\n\tif len(object) != 0 {\n\t\ta.AdditionalProperties = make(map[string]struct {\n\t\t\tFoo *string `json:\"foo,omitempty\"`\n\t\t})\n\t\tfor fieldName, fieldBuf := range object {\n\t\t\tvar fieldVal struct {\n\t\t\t\tFoo *string `json:\"foo,omitempty\"`\n\t\t\t}\n\t\t\terr := json.Unmarshal(fieldBuf, \u0026fieldVal)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error unmarshaling field %s: %w\", fieldName, err)\n\t\t\t}\n\t\t\ta.AdditionalProperties[fieldName] = fieldVal\n\t\t}\n\t}\n\treturn nil\n}\n\n// Override default JSON handling for Thing to handle AdditionalProperties\nfunc (a Thing) MarshalJSON() ([]byte, error) {\n\tvar err error\n\tobject := make(map[string]json.RawMessage)\n\n\tobject[\"id\"], err = json.Marshal(a.Id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling 'id': %w\", err)\n\t}\n\n\tfor fieldName, field := range a.AdditionalProperties {\n\t\tobject[fieldName], err = json.Marshal(field)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error marshaling '%s': %w\", fieldName, err)\n\t\t}\n\t}\n\treturn json.Marshal(object)\n}\n```\n\n\u003c/details\u003e\n\n## Changing the names of generated types\n\nAs of `oapi-codegen` v2.2.0, it is now possible to use the `output-options` configuration's `name-normalizer` to define the logic for how to convert an OpenAPI name (i.e. an Operation ID or a Schema name) and construct a Go type name.\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExample, using default configuration\u003c/summary\u003e\n\nBy default, `oapi-codegen` will perform camel-case conversion, so for a spec such as:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Example code for the `name-normalizer` output option\npaths:\n  /api/pets/{petId}:\n    get:\n      summary: Get pet given identifier.\n      operationId: getHttpPet\n      parameters:\n      - name: petId\n        in: path\n        required: true\n        schema:\n          type: string\n      responses:\n        '200':\n          description: valid pet\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pet'\ncomponents:\n  schemas:\n    Pet:\n      type: object\n      required:\n        - uuid\n        - name\n      properties:\n        uuid:\n          type: string\n          description: The pet uuid.\n        name:\n          type: string\n          description: The name of the pet.\n    Error:\n      required:\n        - code\n        - message\n      properties:\n        code:\n          type: integer\n          format: int32\n          description: Error code\n        message:\n          type: string\n          description: Error message\n    OneOf2things:\n      description: \"Notice that the `things` is not capitalised\"\n      oneOf:\n        - type: object\n          required:\n            - id\n          properties:\n            id:\n              type: integer\n        - type: object\n          required:\n            - id\n          properties:\n            id:\n              type: string\n              format: uuid\n```\n\nThis will produce:\n\n```go\n// OneOf2things Notice that the `things` is not capitalised\ntype OneOf2things struct {\n\tunion json.RawMessage\n}\n\n// Pet defines model for Pet.\ntype Pet struct {\n\t// Name The name of the pet.\n\tName string `json:\"name\"`\n\n\t// Uuid The pet uuid.\n\tUuid string `json:\"uuid\"`\n}\n\n// The interface specification for the client above.\ntype ClientInterface interface {\n\t// GetHttpPet request\n\tGetHttpPet(ctx context.Context, petId string, reqEditors ...RequestEditorFn) (*http.Response, error)\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExample, using \u003ccode\u003eToCamelCaseWithInitialisms\u003c/code\u003e\u003c/summary\u003e\n\nBy default, `oapi-codegen` will perform camel-case conversion, so for a spec such as:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Example code for the `name-normalizer` output option\npaths:\n  /api/pets/{petId}:\n    get:\n      summary: Get pet given identifier.\n      operationId: getHttpPet\n      parameters:\n      - name: petId\n        in: path\n        required: true\n        schema:\n          type: string\n      responses:\n        '200':\n          description: valid pet\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pet'\ncomponents:\n  schemas:\n    Pet:\n      type: object\n      required:\n        - uuid\n        - name\n      properties:\n        uuid:\n          type: string\n          description: The pet uuid.\n        name:\n          type: string\n          description: The name of the pet.\n    Error:\n      required:\n        - code\n        - message\n      properties:\n        code:\n          type: integer\n          format: int32\n          description: Error code\n        message:\n          type: string\n          description: Error message\n    OneOf2things:\n      description: \"Notice that the `things` is not capitalised\"\n      oneOf:\n        - type: object\n          required:\n            - id\n          properties:\n            id:\n              type: integer\n        - type: object\n          required:\n            - id\n          properties:\n            id:\n              type: string\n              format: uuid\n```\n\nThis will produce:\n\n```go\n// OneOf2things Notice that the `things` is not capitalised\ntype OneOf2things struct {\n\tunion json.RawMessage\n}\n\n// Pet defines model for Pet.\ntype Pet struct {\n\t// Name The name of the pet.\n\tName string `json:\"name\"`\n\n\t// UUID The pet uuid.\n\tUUID string `json:\"uuid\"`\n}\n\n// The interface specification for the client above.\ntype ClientInterface interface {\n\t// GetHTTPPet request\n\tGetHTTPPet(ctx context.Context, petID string, reqEditors ...RequestEditorFn) (*http.Response, error)\n}\n```\n\n\u003c/details\u003e\n\n\nFor more details of what the resulting code looks like, check out [the test cases](internal/test/outputoptions/name-normalizer/).\n\n## Examples\n\nThe [examples directory](examples) contains some additional cases which are useful examples for how to use `oapi-codegen`, including how you'd take the Petstore API and implement it with `oapi-codegen`.\n\nYou could also find some cases of how the project can be used by checking out our [internal test cases](internal/test) which are real-world usages that make up our regression tests.\n\n### Blog posts\n\nWe love reading posts by the community about how to use the project.\n\nHere are a few we've found around the Web:\n\n- [Building a Go RESTful API with design-first OpenAPI contracts](https://www.jvt.me/posts/2022/07/12/go-openapi-server/)\n- [A Practical Guide to Using oapi-codegen in Golang API Development with the Fiber Framework](https://medium.com/@fikihalan/a-practical-guide-to-using-oapi-codegen-in-golang-api-development-with-the-fiber-framework-bce2a59380ae)\n- [Generating Go server code from OpenAPI 3 definitions](https://ldej.nl/post/generating-go-from-openapi-3/)\n- [Go Client Code Generation from Swagger and OpenAPI](https://medium.com/@kyodo-tech/go-client-code-generation-from-swagger-and-openapi-a0576831836c)\n- [Go oapi-codegen + request validation](https://blog.commitsmart.com/go-oapi-codegen-request-validation-285398b37dc8)\n- [Streamlining Go + Chi Development: Generating Code from an OpenAPI Spec](https://i4o.dev/blog/oapi-codegen-with-chi-router)\n\nGot one to add? Please raise a PR!\n\n## Frequently Asked Questions (FAQs)\n\n### Does `oapi-codegen` support OpenAPI 3.1?\n\nNo, we don't currently.\n\nOpenAPI 3.1 support is [awaiting upstream support](https://github.com/oapi-codegen/oapi-codegen/issues/373).\n\nIn the meantime, you could follow [steps from this blog post](https://www.jvt.me/posts/2025/05/04/oapi-codegen-trick-openapi-3-1/) to [use OpenAPI Overlay](#modifying-the-input-openapi-specification-with-openapi-overlay) to \"downgrade\" the OpenAPI 3.1 spec to OpenAPI 3.0.\n\n### How does `oapi-codegen` handle `anyOf`, `allOf` and `oneOf`?\n\n`oapi-codegen` supports `anyOf`, `allOf` and `oneOf` for generated code.\n\nFor instance, through the following OpenAPI spec:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: Using complex schemas\n  description: An example of `anyOf`, `allOf` and `oneOf`\ncomponents:\n  schemas:\n    # base types\n    Client:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n    Identity:\n      type: object\n      required:\n        - issuer\n      properties:\n        issuer:\n          type: string\n\n    # allOf performs a union of all types defined\n    ClientWithId:\n      allOf:\n        - $ref: '#/components/schemas/Client'\n        - properties:\n            id:\n              type: integer\n          required:\n            - id\n\n    # allOf performs a union of all types defined, but if there's a duplicate field defined, it'll be overwritten by the last schema\n    # https://github.com/oapi-codegen/oapi-codegen/issues/1569\n    IdentityWithDuplicateField:\n      allOf:\n        # `issuer` will be ignored\n        - $ref: '#/components/schemas/Identity'\n        # `issuer` will be ignored\n        - properties:\n            issuer:\n              type: integer\n        # `issuer` will take precedence\n        - properties:\n            issuer:\n              type: object\n              properties:\n                name:\n                  type: string\n              required:\n                - name\n\n    # anyOf results in a type that has an `AsClient`/`MergeClient`/`FromClient` and an `AsIdentity`/`MergeIdentity`/`FromIdentity` method so you can choose which of them you want to retrieve\n    ClientAndMaybeIdentity:\n      anyOf:\n        - $ref: '#/components/schemas/Client'\n        - $ref: '#/components/schemas/Identity'\n\n    # oneOf results in a type that has an `AsClient`/`MergeClient`/`FromClient` and an `AsIdentity`/`MergeIdentity`/`FromIdentity` method so you can choose which of them you want to retrieve\n    ClientOrIdentity:\n      oneOf:\n        - $ref: '#/components/schemas/Client'\n        - $ref: '#/components/schemas/Identity'\n```\n\nThis results in the following types:\n\n\u003cdetails\u003e\n\n\u003csummary\u003eBase types\u003c/summary\u003e\n\n```go\n// Client defines model for Client.\ntype Client struct {\n\tName string `json:\"name\"`\n}\n\n// Identity defines model for Identity.\ntype Identity struct {\n\tIssuer string `json:\"issuer\"`\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003ccode\u003eallOf\u003c/code\u003e\u003c/summary\u003e\n\n```go\n// ClientWithId defines model for ClientWithId.\ntype ClientWithId struct {\n\tId   int    `json:\"id\"`\n\tName string `json:\"name\"`\n}\n\n// IdentityWithDuplicateField defines model for IdentityWithDuplicateField.\ntype IdentityWithDuplicateField struct {\n\tIssuer struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"issuer\"`\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003ccode\u003eanyOf\u003c/code\u003e\u003c/summary\u003e\n\n```go\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/oapi-codegen/runtime\"\n)\n\n// ClientAndMaybeIdentity defines model for ClientAndMaybeIdentity.\ntype ClientAndMaybeIdentity struct {\n\tunion json.RawMessage\n}\n\n// AsClient returns the union data inside the ClientAndMaybeIdentity as a Client\nfunc (t ClientAndMaybeIdentity) AsClient() (Client, error) {\n\tvar body Client\n\terr := json.Unmarshal(t.union, \u0026body)\n\treturn body, err\n}\n\n// FromClient overwrites any union data inside the ClientAndMaybeIdentity as the provided Client\nfunc (t *ClientAndMaybeIdentity) FromClient(v Client) error {\n\tb, err := json.Marshal(v)\n\tt.union = b\n\treturn err\n}\n\n// MergeClient performs a merge with any union data inside the ClientAndMaybeIdentity, using the provided Client\nfunc (t *ClientAndMaybeIdentity) MergeClient(v Client) error {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmerged, err := runtime.JSONMerge(t.union, b)\n\tt.union = merged\n\treturn err\n}\n\n// AsIdentity returns the union data inside the ClientAndMaybeIdentity as a Identity\nfunc (t ClientAndMaybeIdentity) AsIdentity() (Identity, error) {\n\tvar body Identity\n\terr := json.Unmarshal(t.union, \u0026body)\n\treturn body, err\n}\n\n// FromIdentity overwrites any union data inside the ClientAndMaybeIdentity as the provided Identity\nfunc (t *ClientAndMaybeIdentity) FromIdentity(v Identity) error {\n\tb, err := json.Marshal(v)\n\tt.union = b\n\treturn err\n}\n\n// MergeIdentity performs a merge with any union data inside the ClientAndMaybeIdentity, using the provided Identity\nfunc (t *ClientAndMaybeIdentity) MergeIdentity(v Identity) error {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmerged, err := runtime.JSONMerge(t.union, b)\n\tt.union = merged\n\treturn err\n}\n\nfunc (t ClientAndMaybeIdentity) MarshalJSON() ([]byte, error) {\n\tb, err := t.union.MarshalJSON()\n\treturn b, err\n}\n\nfunc (t *ClientAndMaybeIdentity) UnmarshalJSON(b []byte) error {\n\terr := t.union.UnmarshalJSON(b)\n\treturn err\n}\n\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003ccode\u003eoneOf\u003c/code\u003e\u003c/summary\u003e\n\n```go\n// AsClient returns the union data inside the ClientOrIdentity as a Client\nfunc (t ClientOrIdentity) AsClient() (Client, error) {\n\tvar body Client\n\terr := json.Unmarshal(t.union, \u0026body)\n\treturn body, err\n}\n\n// FromClient overwrites any union data inside the ClientOrIdentity as the provided Client\nfunc (t *ClientOrIdentity) FromClient(v Client) error {\n\tb, err := json.Marshal(v)\n\tt.union = b\n\treturn err\n}\n\n// MergeClient performs a merge with any union data inside the ClientOrIdentity, using the provided Client\nfunc (t *ClientOrIdentity) MergeClient(v Client) error {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmerged, err := runtime.JSONMerge(t.union, b)\n\tt.union = merged\n\treturn err\n}\n\n// AsIdentity returns the union data inside the ClientOrIdentity as a Identity\nfunc (t ClientOrIdentity) AsIdentity() (Identity, error) {\n\tvar body Identity\n\terr := json.Unmarshal(t.union, \u0026body)\n\treturn body, err\n}\n\n// FromIdentity overwrites any union data inside the ClientOrIdentity as the provided Identity\nfunc (t *ClientOrIdentity) FromIdentity(v Identity) error {\n\tb, err := json.Marshal(v)\n\tt.union = b\n\treturn err\n}\n\n// MergeIdentity performs a merge with any union data inside the ClientOrIdentity, using the provided Identity\nfunc (t *ClientOrIdentity) MergeIdentity(v Identity) error {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmerged, err := runtime.JSONMerge(t.union, b)\n\tt.union = merged\n\treturn err\n}\n\nfunc (t ClientOrIdentity) MarshalJSON() ([]byte, error) {\n\tb, err := t.union.MarshalJSON()\n\treturn b, err\n}\n\nfunc (t *ClientOrIdentity) UnmarshalJSON(b []byte) error {\n\terr := t.union.UnmarshalJSON(b)\n\treturn err\n}\n```\n\n\u003c/details\u003e\n\nFor more info, check out [the example code](examples/anyof-allof-oneof/).\n\n### How can I ignore parts of the spec I don't care about?\n\nBy default, `oapi-codegen` will generate everything from the specification.\n\nIf you'd like to reduce what's generated, you can use one of a few options in [the configuration file](#usage) to tune the generation of the resulting output:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json\noutput-options:\n  include-tags: []\n  exclude-tags: []\n  include-operation-ids: []\n  exclude-operation-ids: []\n  exclude-schemas: []\n```\n\nCheck [the docs](https://pkg.go.dev/github.com/oapi-codegen/oapi-codegen/v2/pkg/codegen#OutputOptions) for more details of usage.\n\n### Should I commit the generated code?\n\nWe recommend doing so, yes, for the following reasons:\n\n- It means it's easier to view the impact of a change - be it due to an upgrade of `oapi-codegen`, or a change to your spec - and has helped catch (possibly) breaking changes in the past more easily\n- It then allows your codebase to be consumed as a library, as all the files are committed\n\nThis means you'll need to have your CI/CD pipeline validate that generated files are all up-to-date, but that's a fairly straightforward piece of work.\n\n### Should I lint the generated code?\n\nWe really ask that you don't. Although it intends to be idiomatic Go code, it's not expected to pass all the various linting rules that your project may apply.\n\n\u003e [!NOTE]\n\u003e We will, on occasion, improve the generated code to fix some linting warnings, such as those from `go vet`, but this should not be an expected change.\n\n### I've just updated my version of `kin-openapi`, and now I can't build my code 😠\n\nThe [kin-openapi](https://github.com/getkin/kin-openapi) project - which we 💜 for providing a great library and set of tooling for interacting with OpenAPI - is a pre-v1 release, which means that they're within their rights to push breaking changes.\n\nThis may lead to breakage in your consuming code, and if so, sorry that's happened!\n\nWe'll be aware of the issue, and will work to update both the core `oapi-codegen` and the middlewares accordingly.\n\n## Contributors\n\nWe're very appreciative of [the many contributors over the years](https://github.com/oapi-codegen/oapi-codegen/graphs/contributors) and the ongoing use of the project 💜\n\n\u003ca href=\"https://github.com/oapi-codegen/oapi-codegen/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=oapi-codegen/oapi-codegen\" /\u003e\n\u003c/a\u003e\n\n## Sponsors\n\nFor the most part, `oapi-codegen` is maintained in two busy peoples' free time. As noted in [Creating a more sustainable model for `oapi-codegen` in the future](https://github.com/oapi-codegen/oapi-codegen/discussions/1606), we're looking to make this a more sustainable project in the future.\n\nPlease consider sponsoring us through GitHub Sponsors either [on the organisation](https://github.com/sponsors/oapi-codegen/) or [directly for Jamie](https://github.com/sponsors/jamietanna/), which helps work towards us being able to maintain the project long term.\n\nSee [this blog post from Tidelift](https://blog.tidelift.com/paying-maintainers-the-howto) for more details on how to talk to your company about sponsoring maintainers of (Open Source) projects you depend on.\n\nWe are currently sponsored for 4 hours of work a month by Elastic:\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://elastic.co?utm_source=oapi-codegen+repo\u0026utm_medium=github+sponsorship\"\u003e\n\t\t\u003cpicture\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\".github/sponsors/elastic-light.svg\"\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\".github/sponsors/elastic-dark.svg\"\u003e\n\t\t  \u003cimg alt=\"Elastic logo\" src=\".github/sponsors/elastic-dark.svg\" height=\"100px\"\u003e\n\t\t\u003c/picture\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\nIn addition, we are also generously sponsored by the following folks, each of whom provide sponsorship for 1 hour of work a month:\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://www.devzero.io/lp/dev-environment?utm_campaign=github\u0026utm_source=oapi-codegen%20repo\u0026utm_medium=github%20sponsorship\"\u003e\n\t\t\u003cpicture\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\".github/sponsors/devzero-light.svg\"\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\".github/sponsors/devzero-dark.svg\"\u003e\n\t\t  \u003cimg alt=\"DevZero logo\" src=\".github/sponsors/devzero-dark.svg\" height=\"100px\"\u003e\n\t\t\u003c/picture\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://sandbox.speakeasy.com/?s=iQ5hEdrjLCii\u0026utm_source=oapi-codegen+repo\u0026utm_medium=github+sponsorship\"\u003e\n\t\t\u003cpicture\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\".github/sponsors/speakeasy-light.svg\"\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\".github/sponsors/speakeasy-dark.svg\"\u003e\n\t\t  \u003cimg alt=\"Speakeasy logo\" src=\".github/sponsors/speakeasy-dark.svg\" height=\"100px\"\u003e\n\t\t\u003c/picture\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://cybozu.co.jp/?utm_source=oapi-codegen+repo\u0026utm_medium=github+sponsorship\"\u003e\n\t\t\u003cimg alt=\"Cybozu logo\" src=\".github/sponsors/cybozu.svg\" height=\"100px\"\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://livepeer.org/?utm_source=oapi-codegen+repo\u0026utm_medium=github+sponsorship\"\u003e\n\t\t\u003cpicture\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\".github/sponsors/livepeer-light.svg\"\u003e\n\t\t  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\".github/sponsors/livepeer-dark.svg\"\u003e\n\t\t  \u003cimg alt=\"Livepeer logo\" src=\".github/sponsors/livepeer-dark.svg\" height=\"50px\"\u003e\n\t\t\u003c/picture\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n(Note that the order of appearance the order in which sponsorship was received)\n","funding_links":["https://github.com/sponsors/oapi-codegen","https://github.com/sponsors/jamietanna","https://opencollective.com/oapi-codegen","https://github.com/sponsors/oapi-codegen/","https://github.com/sponsors/jamietanna/","https://blog.tidelift.com/paying-maintainers-the-howto"],"categories":["Go","HarmonyOS","API tools","rest-api","Generators","Popular Frameworks"],"sub_categories":["Windows Manager","Threat modelling","Search and Analytic Databases","OpenAPI and Swagger Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foapi-codegen%2Foapi-codegen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foapi-codegen%2Foapi-codegen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foapi-codegen%2Foapi-codegen/lists"}