[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93526":3},{"id":4,"name":5,"fullName":6,"owner":5,"repo":5,"description":7,"homepage":8,"htmlUrl":9,"language":10,"languages":8,"totalLinesOfCode":8,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":8,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":16,"compositeScore":17,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":18,"hasPages":18,"topics":8,"createdAt":8,"pushedAt":8,"updatedAt":20,"readmeContent":21,"aiSummary":8,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":22,"discoverSource":23},93526,"oapi-codegen","oapi-codegen\u002Foapi-codegen","Generate Go client and server boilerplate from OpenAPI 3 specifications",null,"https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen","Go",8461,1047,41,245,0,2,63.26,false,"main","2026-07-22 04:02:09","# `oapi-codegen`\n\n[![OpenSSF Best Practices](https:\u002F\u002Fwww.bestpractices.dev\u002Fprojects\u002F9450\u002Fbadge)](https:\u002F\u002Fwww.bestpractices.dev\u002Fprojects\u002F9450)\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:\u002F\u002Fgithub.com\u002FOAI\u002FOpenAPI-Specification\u002Fblob\u002Fmain\u002Fversions\u002F3.0.0.md) and [OpenAPI 3.1](https:\u002F\u002Fgithub.com\u002FOAI\u002FOpenAPI-Specification\u002Fblob\u002Fmain\u002Fversions\u002F3.1.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 verbose code over complex modular code\n- supporting as much of OpenAPI 3.0 and 3.1 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:\u002F\u002Fgithub.com\u002Foapi-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## Table of Contents\n\n\u003C!-- toc -->\n- [Installation](#installation)\n  - [Action Required: The repository for this project has changed](#action-required-the-repository-for-this-project-has-changed)\n  - [Installing](#installing)\n  - [Pinning to commits](#pinning-to-commits)\n- [Usage](#usage)\n  - [Backwards compatibility](#backwards-compatibility)\n- [Features](#features)\n- [What does it look like?](#what-does-it-look-like)\n- [Key design decisions](#key-design-decisions)\n- [Generating server-side boilerplate](#generating-server-side-boilerplate)\n  - [Supported Servers](#supported-servers)\n  - [Strict server](#strict-server)\n- [Generating API clients](#generating-api-clients)\n  - [With Server URLs](#with-server-urls)\n  - [Duplicate types generated for clients's response object types](#duplicate-types-generated-for-clientss-response-object-types)\n- [Generating API models](#generating-api-models)\n- [Splitting large OpenAPI specs across multiple packages (aka &quot;Import Mapping&quot; or &quot;external references&quot;)](#splitting-large-openapi-specs-across-multiple-packages-aka-import-mapping-or-external-references)\n  - [Using a single package with multiple OpenAPI specs](#using-a-single-package-with-multiple-openapi-specs)\n  - [Using multiple packages, with one OpenAPI spec per package](#using-multiple-packages-with-one-openapi-spec-per-package)\n- [Modifying the input OpenAPI Specification (with OpenAPI Overlay)](#modifying-the-input-openapi-specification-with-openapi-overlay)\n- [Generating Nullable types](#generating-nullable-types)\n- [OpenAPI extensions](#openapi-extensions)\n- [Request\u002Fresponse validation middleware](#requestresponse-validation-middleware)\n- [Implementing security](#implementing-security)\n  - [On the server](#on-the-server)\n    - [Deprecated: auth scopes on the request context](#deprecated-auth-scopes-on-the-request-context)\n  - [On the client](#on-the-client)\n- [Custom code generation](#custom-code-generation)\n  - [Local paths](#local-paths)\n  - [HTTPS paths](#https-paths)\n  - [Inline template](#inline-template)\n  - [Using the Go package](#using-the-go-package)\n- [Additional Properties (\u003Ccode>additionalProperties\u003C\u002Fcode>)](#additional-properties-additionalproperties)\n  - [Implicit \u003Ccode>additionalProperties: true\u003C\u002Fcode> \u002F no \u003Ccode>additionalProperties\u003C\u002Fcode> set](#implicit-additionalproperties-true--no-additionalproperties-set)\n  - [Explicit \u003Ccode>additionalProperties: true\u003C\u002Fcode>](#explicit-additionalproperties-true)\n  - [\u003Ccode>additionalProperties\u003C\u002Fcode> as \u003Ccode>integer\u003C\u002Fcode>s](#additionalproperties-as-integers)\n  - [\u003Ccode>additionalProperties\u003C\u002Fcode> with an object](#additionalproperties-with-an-object)\n- [Globally skipping the &quot;optional pointer&quot;](#globally-skipping-the-optional-pointer)\n- [Changing the names of generated types](#changing-the-names-of-generated-types)\n- [Examples](#examples)\n  - [Blog posts](#blog-posts)\n- [Frequently Asked Questions (FAQs)](#frequently-asked-questions-faqs)\n  - [Does \u003Ccode>oapi-codegen\u003C\u002Fcode> support OpenAPI 3.1?](#does-oapi-codegen-support-openapi-31)\n  - [How does \u003Ccode>oapi-codegen\u003C\u002Fcode> handle \u003Ccode>anyOf\u003C\u002Fcode>, \u003Ccode>allOf\u003C\u002Fcode> and \u003Ccode>oneOf\u003C\u002Fcode>?](#how-does-oapi-codegen-handle-anyof-allof-and-oneof)\n  - [How can I ignore parts of the spec I don't care about?](#how-can-i-ignore-parts-of-the-spec-i-dont-care-about)\n  - [Should I commit the generated code?](#should-i-commit-the-generated-code)\n  - [Should I lint the generated code?](#should-i-lint-the-generated-code)\n  - [I've just updated my version of \u003Ccode>kin-openapi\u003C\u002Fcode>, and now I can't build my code 😠](#ive-just-updated-my-version-of-kin-openapi-and-now-i-cant-build-my-code-)\n- [Contributors](#contributors)\n- [Sponsors](#sponsors)\n\u003C!-- \u002Ftoc -->\n\n## Installation\n\n### Action Required: The repository for this project has changed\n\nAs announced in [May 2024](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fdiscussions\u002F1605),\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\u002Freplace from\n`github.com\u002Fdeepmap\u002Foapi-codegen\u002Fv2` to `github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2`.\n\n> [!IMPORTANT]\n> `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\u002Fdeepmap\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen@latest\n```\n\n### Installing\n\n`oapi-codegen` requires Go 1.25+ to build and install. Note that the *generated* code has its own, lower requirements — see [Supported Servers](#supported-servers).\n\nIt is recommended to use [`go tool` support](https:\u002F\u002Fwww.jvt.me\u002Fposts\u002F2025\u002F01\u002F27\u002Fgo-tools-124\u002F) 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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-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\u002F\u002Fgo:generate go tool oapi-codegen -config cfg.yaml ..\u002F..\u002Fapi.yaml\n```\n\nAlternatively, you can install it as a binary with:\n\n```sh\n$ go install github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen@latest\n$ oapi-codegen -version\n```\n\nWhich then means you can invoke it like so:\n\n```go\n\u002F\u002Fgo:generate oapi-codegen --config=config.yaml ..\u002F..\u002Fapi.yaml\n```\n\n### Pinning to commits\n\nWhile the project does not ([yet](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1519)) 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\u002Fbug 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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2@main\n# alternatively, to a commit hash i.e. https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fcommit\u002F71e916c59688a6379b5774dfe5904ec222b9a537\n$ go get github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2@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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2 v2.1.0\n+require github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2 v2.1.1-0.20240331212514-80f0b978ef16\n```\n\n## Usage\n\n`oapi-codegen` is 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.\nWhile some command line options are supported, they should be considered deprecated,\nwe just maintain them for backward compatibility, but we're not extending\nthem.\n\nFor full details of what is supported, check out the [oapi-codegen configuration documentation](docs\u002Fconfiguration.md).\n\nWe also have [a JSON Schema](configuration-schema.json) that can be used by IDEs\u002Feditors with the Language Server Protocol (LSP) to perform intelligent suggestions, i.e.:\n\n```yaml\n# yaml-language-server: $schema=https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\npackage: api\n# ...\n```\n\nNote that it's recommended to pin to a specific version of the configuration schema, so it matches the version of `oapi-codegen` you're using. For instance, if you're using [Renovate](https:\u002F\u002Fdocs.renovatebot.com\u002F), you can [have Renovate automagically update this version for you](https:\u002F\u002Fwww.jvt.me\u002Fposts\u002F2026\u002F03\u002F01\u002Foapi-codegen-config-renovate\u002F).\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:\u002F\u002Fxkcd.com\u002F1172\u002F).\n\nIn this case, we will expose a [compatibility option](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fpkg\u002Fcodegen#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 \u002F 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\u002Fpetstore-expanded\u002Fstdhttp\u002Fapi\u002Fpetstore.gen.go):\n\n```go\n\u002F\u002F generated code\n\ntype ServerInterface interface {\n\t\u002F\u002F ...\n\t\u002F\u002F Returns all pets\n\t\u002F\u002F (GET \u002Fpets)\n\tFindPets(w http.ResponseWriter, r *http.Request, params FindPetsParams)\n\t\u002F\u002F ...\n}\n\n\u002F\u002F FindPets operation middleware\nfunc (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) {\n\n\tvar err error\n\n\t\u002F\u002F Parameter object where we will unmarshal all parameters from the context\n\tvar params FindPetsParams\n\n\t\u002F\u002F ------------- Optional query parameter \"tags\" -------------\n\n\terr = runtime.BindQueryParameter(\"form\", true, false, \"tags\", r.URL.Query(), &params.Tags)\n\tif err != nil {\n\t\tsiw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: \"tags\", Err: err})\n\t\treturn\n\t}\n\n\t\u002F\u002F ------------- Optional query parameter \"limit\" -------------\n\n\terr = runtime.BindQueryParameter(\"form\", true, false, \"limit\", r.URL.Query(), &params.Limit)\n\tif err != nil {\n\t\tsiw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{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\u002F\u002F 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+\"\u002Fpets\", 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\u002F\u002F Make sure we conform to ServerInterface\n\nvar _ ServerInterface = (*PetStore)(nil)\n\nfunc NewPetStore() *PetStore {\n\treturn &PetStore{\n\t\tPets:   make(map[int64]Pet),\n\t\tNextId: 1000,\n\t}\n}\n\n\u002F\u002F 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\u002F\u002F If we have tags,  filter pets by tag\n\t\t\tfor _, t := range *params.Tags {\n\t\t\t\tif pet.Tag != nil && (*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\u002F\u002F 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) >= l {\n\t\t\t\t\u002F\u002F 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\u002Fresponse data, which is further reduced by using the [Strict server](#strict-server) functionality.\n\n\u003Ca name=\"what-does-it-look-like-strict\">\u003C\u002Fa>\nWhen using the strict server, you'll have the following generated code:\n\n```go\n\u002F\u002F StrictServerInterface represents all server handlers.\ntype StrictServerInterface interface {\n\t\u002F\u002F ...\n\t\u002F\u002F Returns all pets\n\t\u002F\u002F (GET \u002Fpets)\n\tFindPets(ctx context.Context, request FindPetsRequestObject) (FindPetsResponseObject, error)\n\t\u002F\u002F ...\n}\n\nfunc NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface {\n\treturn &strictHandler{ssi: ssi, middlewares: middlewares, options: options}\n}\n\n\u002F\u002F 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\u002F\u002F Make sure we conform to StrictServerInterface\n\nvar _ StrictServerInterface = (*PetStore)(nil)\n\nfunc NewPetStore() *PetStore {\n\treturn &PetStore{\n\t\tPets:   make(map[int64]Pet),\n\t\tNextId: 1000,\n\t}\n}\n\n\u002F\u002F 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\u002F\u002F 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 && (*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\u002F\u002F 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) >= l {\n\t\t\t\t\u002F\u002F 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\u002Ftemplate`s, which are user-overridable\n- Attempts to produce idiomatic Go\n- Support multiple OpenAPI files by having a package per OpenAPI file\n- Support of OpenAPI 3.0 and 3.1\n  - OpenAPI 3.1 support includes [webhooks](https:\u002F\u002Fspec.openapis.org\u002Foas\u002Fv3.1.0#oasWebhooks) and version-aware handling of 3.1 idioms such as `type: [T, \"null\"]` nullability and enums declared via `oneOf` + `const`\n  - Note that this does not include OpenAPI 2.0 (aka Swagger). If you have an old Swagger\n    specification, you can use a [converter](https:\u002F\u002Fconverter.swagger.io\u002F) before\n    using oapi-codegen.\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\nYou can find the supported HTTP server backends below, and more information about how to implement a server on top of each router.\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\u002Fgo\u002Fvalidator](https:\u002F\u002Fopenapi.tanna.dev\u002Fgo\u002Fvalidator\u002F), or craft your own.\n\n### Supported Servers\n\nRight now, we support the following servers, and are supportive of adding new servers, too! Each\nserver lists a minimum require Go version to compile the generated code, which may\nbe different from that of oapi-codegen itself. While the code may compile on an\nolder version of Go, we don't promise that it'll work.\n\n| Server | `generate` flag | Go Version | Documentation |\n| --- | --- |------------| --- |\n| [Chi](https:\u002F\u002Fgithub.com\u002Fgo-chi\u002Fchi) | `chi-server` | 1.24+      | [Chi documentation](docs\u002Fchi-server.md) |\n| [Echo](https:\u002F\u002Fgithub.com\u002Flabstack\u002Fecho) | `echo-server` | 1.24+      | [Echo documentation](docs\u002Fecho-server.md) |\n| [Echo v5](https:\u002F\u002Fgithub.com\u002Flabstack\u002Fecho) | `echo5-server` | 1.25+      | [Echo v5 documentation](docs\u002Fecho5-server.md) |\n| [Fiber](https:\u002F\u002Fgithub.com\u002Fgofiber\u002Ffiber) | `fiber-server` | 1.24+      | [Fiber documentation](docs\u002Ffiber-server.md) |\n| [Fiber v3](https:\u002F\u002Fgithub.com\u002Fgofiber\u002Ffiber) | `fiber-v3-server` | 1.25+      | [Fiber v3 documentation](docs\u002Ffiber-v3-server.md) |\n| [Gin](https:\u002F\u002Fgithub.com\u002Fgin-gonic\u002Fgin) | `gin-server` | 1.25+      | [Gin documentation](docs\u002Fgin-server.md) |\n| [gorilla\u002Fmux](https:\u002F\u002Fgithub.com\u002Fgorilla\u002Fmux) | `gorilla-server` | 1.24+      | [gorilla\u002Fmux documentation](docs\u002Fgorilla-server.md) |\n| [Iris](https:\u002F\u002Fgithub.com\u002Fkataras\u002Firis) | `iris-server` | 1.24+      | [Iris documentation](docs\u002Firis-server.md) |\n| [`net\u002Fhttp`](https:\u002F\u002Fpkg.go.dev\u002Fnet\u002Fhttp) | `std-http-server` | 1.24+      | [`net\u002Fhttp` documentation](docs\u002Fstdhttp-server.md) |\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\u002Fresponse media types and status codes on a given operation\n- first-class support for `multipart\u002Fform-data` and `application\u002Fx-www-form-urlencoded` requests\n- returning an [HTTP 500 Internal Server Error](https:\u002F\u002Fhttp.cat\u002F500), when an `error` is returned from a function\n- automagic (un)marshalling of request\u002Fresponses, 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> [!NOTE]\n> 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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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> [!NOTE]\n> This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).\n\n> [!IMPORTANT]\n> When a strict-server spec uses `$ref` to point at a `components\u002Fresponses\u002F...` (or `components\u002FrequestBodies\u002F...`) defined in another spec via `import-mapping`, the destination spec **must also be generated with `strict-server: true`**. The strict envelope embeds the `\u003CName>JSONResponse` type from the destination package; that type only exists when the destination generates a strict server. Without it the generated code will fail to compile with an \"undefined\" error. See [issue #2010](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F2010).\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\u002For 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  \u002Fclient:\n    get:\n      operationId: getClient\n      responses:\n        200:\n          content:\n            application\u002Fjson:\n              schema:\n                $ref: \"#\u002Fcomponents\u002Fschemas\u002FClientType\"\n    put:\n      operationId: updateClient\n      responses:\n        400:\n          content:\n            application\u002Fjson:\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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002F\u002Fgo:generate go run github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen -config cfg.yaml api.yaml\n```\n\nThis would then generate:\n\n```go\npackage client\n\n\u002F\u002F ...\n\n\u002F\u002F ClientType defines model for ClientType.\ntype ClientType struct {\n\tName string `json:\"name\"`\n}\n\n\u002F\u002F ...\n\n\u002F\u002F Client which conforms to the OpenAPI3 specification for this service.\ntype Client struct {\n\t\u002F\u002F The endpoint of the server conforming to this interface, with scheme,\n\t\u002F\u002F https:\u002F\u002Fapi.deepmap.com for example. This can contain a path relative\n\t\u002F\u002F to the server, such as https:\u002F\u002Fapi.deepmap.com\u002Fdev-test, and all the\n\t\u002F\u002F paths in the swagger spec will be appended to the server.\n\tServer string\n\n\t\u002F\u002F Doer for performing requests, typically a *http.Client with any\n\t\u002F\u002F customized settings, such as certificate chains.\n\tClient HttpRequestDoer\n\n\t\u002F\u002F A list of callbacks for modifying requests which are generated before sending over\n\t\u002F\u002F the network.\n\tRequestEditors []RequestEditorFn\n}\n\n\u002F\u002F ...\n\n\u002F\u002F The interface specification for the client above.\ntype ClientInterface interface {\n\t\u002F\u002F GetClient request\n\tGetClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)\n\n\t\u002F\u002F UpdateClient request\n\tUpdateClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)\n}\n\n\u002F\u002F ...\n\n\u002F\u002F ClientWithResponsesInterface is the interface specification for the client with responses above.\ntype ClientWithResponsesInterface interface {\n\t\u002F\u002F GetClientWithResponse request\n\tGetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error)\n\n\t\u002F\u002F 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\u002F\u002F ...\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\u002Fhttp\"\n\n\t\"github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fexamples\u002Fclient\"\n)\n\nfunc TestClient_canCall() {\n\t\u002F\u002F custom HTTP client\n\thc := http.Client{}\n\n\t\u002F\u002F with a raw http.Response\n\t{\n\t\tc, err := client.NewClient(\"http:\u002F\u002Flocalhost:1234\", client.WithHTTPClient(&hc))\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\u002F\u002F or to get a struct with the parsed response body\n\t{\n\t\tc, err := client.NewClientWithResponses(\"http:\u002F\u002Flocalhost:1234\", client.WithHTTPClient(&hc))\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### With Server URLs\n\nAn OpenAPI specification makes it possible to denote Servers that a client can interact with, such as:\n\n```yaml\nservers:\n- url: https:\u002F\u002Fdevelopment.gigantic-server.com\u002Fv1\n  description: Development server\n- url: https:\u002F\u002F{username}.gigantic-server.com:{port}\u002F{basePath}\n  description: The production API server\n  variables:\n    username:\n      # note! no enum here means it is an open value\n      default: demo\n      description: this value is assigned by the service provider, in this example `gigantic-server.com`\n    port:\n      enum:\n        - '8443'\n        - '443'\n      default: '8443'\n    basePath:\n      # open meaning there is the opportunity to use special base paths as assigned by the provider, default is `v2`\n      default: v2\n```\n\nIt is possible to opt-in to the generation of these Server URLs with the following configuration:\n\n```yaml\n# yaml-language-server: $schema=https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\npackage: serverurls\noutput: gen.go\ngenerate:\n  # NOTE that this uses default settings - if you want to use initialisms to generate i.e. `ServerURLDevelopmentServer`, you should look up the `output-options.name-normalizer` configuration\n  server-urls: true\n```\n\nThis will then generate the following boilerplate:\n\n```go\n\u002F\u002F (the below does not include comments that are generated)\n\nconst ServerUrlDevelopmentServer = \"https:\u002F\u002Fdevelopment.gigantic-server.com\u002Fv1\"\n\ntype ServerUrlTheProductionAPIServerBasePathVariable string\nconst ServerUrlTheProductionAPIServerBasePathVariableDefault = \"v2\"\n\ntype ServerUrlTheProductionAPIServerPortVariable string\nconst ServerUrlTheProductionAPIServerPortVariable8443 ServerUrlTheProductionAPIServerPortVariable = \"8443\"\nconst ServerUrlTheProductionAPIServerPortVariable443 ServerUrlTheProductionAPIServerPortVariable = \"443\"\nconst ServerUrlTheProductionAPIServerPortVariableDefault ServerUrlTheProductionAPIServerPortVariable = ServerUrlTheProductionAPIServerPortVariable8443\n\ntype ServerUrlTheProductionAPIServerUsernameVariable string\nconst ServerUrlTheProductionAPIServerUsernameVariableDefault = \"demo\"\n\nfunc ServerUrlTheProductionAPIServer(basePath ServerUrlTheProductionAPIServerBasePathVariable, port ServerUrlTheProductionAPIServerPortVariable, username ServerUrlTheProductionAPIServerUsernameVariable) (string, error) {\n    \u002F\u002F ...\n}\n```\n\nNotice that for URLs that are not templated, a simple `const` definition is created.\n\nHowever, for more complex URLs that defined `variables` in them, we generate the types (and any `enum` values or `default` values), and instead use a function to create the URL.\n\nFor a complete example see [`examples\u002Fgenerate\u002Fserverurls`](examples\u002Fgenerate\u002Fserverurls).\n\n### Duplicate types generated for clients's response object types\n\nWhen generating the types for interacting with the generated client, `oapi-codegen` will use the `operationId` and add on a `Request` or `Response` suffix.\n\nHowever, this can clash if you have named your component schemas in a similar way.\n\nFor instance:\n\n```yaml\nopenapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: \"Show that generated client boilerplate can clash if schemas are well named i.e. `*Request` and `*Response`\"\npaths:\n  \u002Fclient:\n    put:\n      operationId: updateClient\n      requestBodies:\n        application\u002Fjson:\n          schema:\n            $ref: '#\u002Fcomponents\u002Fschemas\u002FUpdateClientRequest'\n      responses:\n        400:\n          content:\n            application\u002Fjson:\n              schema:\n                $ref: '#\u002Fcomponents\u002Fschemas\u002FUpdateClientResponse'\ncomponents:\n  schemas:\n    UpdateClientRequest:\n      type: object\n      properties:\n        code:\n          type: string\n      required:\n      - code\n    UpdateClientResponse:\n      type: object\n      required:\n        - name\n      properties:\n        name:\n          type: string\n```\n\nIf you were to generate with this configuration:\n\n```yaml\n# yaml-language-server: $schema=https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\npackage: client\noutput: client.gen.go\ngenerate:\n  models: true\n  client: true\n```\n\nThis would then result in `go build` failures:\n\n```\n# github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fexamples\u002Fclienttypenameclash\n.\u002Fclient.gen.go:184:6: UpdateClientResponse redeclared in this block\n        .\u002Fclient.gen.go:17:6: other declaration of UpdateClientResponse\n.\u002Fclient.gen.go:192:7: r.HTTPResponse undefined (type UpdateClientResponse has no field or method HTTPResponse)\n.\u002Fclient.gen.go:193:12: r.HTTPResponse undefined (type UpdateClientResponse has no field or method HTTPResponse)\n.\u002Fclient.gen.go:200:7: r.HTTPResponse undefined (type UpdateClientResponse has no field or method HTTPResponse)\n.\u002Fclient.gen.go:201:12: r.HTTPResponse undefined (type UpdateClientResponse has no field or method HTTPResponse)\n.\u002Fclient.gen.go:224:3: unknown field Body in struct literal of type UpdateClientResponse\n.\u002Fclient.gen.go:225:3: unknown field HTTPResponse in struct literal of type UpdateClientResponse\n.\u002Fclient.gen.go:234:12: response.JSON400 undefined (type *UpdateClientResponse has no field or method JSON400)\n```\n\nTo fix this, use the `response-type-suffix` Output Option:\n\n```diff\n # yaml-language-server: $schema=https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\n package: client\n output: client.gen.go\n generate:\n   models: true\n   client: true\n+output-options:\n+  response-type-suffix: Resp\n```\n\nThis will then rename the generated types from the default to use the new suffix:\n\n```diff\n-type UpdateClientResponse struct {\n+type UpdateClientResp struct {\n        Body         []byte\n        HTTPResponse *http.Response\n        JSON400      *UpdateClientResponse\n }\n```\n\nThere is no currently planned work to change this behaviour.\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> [!TIP]\n> Try to define as much as possible within the `#\u002Fcomponents\u002Fschemas` object, as `oapi-codegen` will generate all the types here.\n>\n> 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  \u002Fclient:\n    get:\n      operationId: getClient\n      responses:\n        200:\n          content:\n            application\u002Fjson:\n              schema:\n                # NOTE that Client is generated here, because it's within #\u002Fcomponents\u002Fschemas\n                $ref: \"#\u002Fcomponents\u002Fschemas\u002FClient\"\n    put:\n      operationId: updateClient\n      responses:\n        400:\n          content:\n            application\u002Fjson:\n              # NOTE that this anonymous object is \u002Fnot\u002F generated because it's an anonymous, but would be generated if using `generate: client`\n              # See https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1512\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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002F\u002Fgo:generate go run github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen -config cfg.yaml api.yaml\n```\n\nThis would then generate:\n\n```go\npackage onlymodels\n\n\u002F\u002F 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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002Fonly-models`](examples\u002Fonly-models).\n\n## Splitting large OpenAPI specs across multiple packages (aka \"Import Mapping\" or \"external references\")\n\u003Ca name=import-mapping>\u003C\u002Fa>\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\u002Fjson:\n              schema:\n                $ref: '#\u002Fcomponents\u002Fschemas\u002FUser'\n```\n\nThis is supported by `oapi-codegen`, through the ability to perform \"Import Mapping\".\n\n> [!NOTE]\n> The keys of `import-mapping` are the paths of the `$ref`'d documents — a relative file path or a URL, exactly as it is written in the `$ref` — and the values are the Go packages their types are generated into.\n>\n> A key cannot be a JSON pointer such as `#\u002Fcomponents\u002Fschemas`. References within a single document always resolve to the package being generated, so there's nothing to map — if you want your models in a different Go package to your server, split them into their own spec file and map that file, as shown below.\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\u002Fapi.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  \u002Fadmin\u002Fuser\u002F{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\u002Fjson:\n              schema:\n                $ref: '..\u002Fcommon\u002Fapi.yaml#\u002Fcomponents\u002Fschemas\u002FUser'\n```\n\nThis references the common spec:\n\n```yaml\n# common\u002Fapi.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>\u003C\u002Fa>\n\n> [!TIP]\n> 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>\n> This is an improvement on the previous model, which would require splitting files across multiple packages.\n\n> [!NOTE]\n> 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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen -config cfg-api.yaml ..\u002Fadmin\u002Fapi.yaml\n$ go run github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fcmd\u002Foapi-codegen -config cfg-user.yaml ..\u002Fcommon\u002Fapi.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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002Fsamepackage example](examples\u002Fimport-mapping\u002Fsamepackage) 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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\n# admin\u002Fcfg.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 (..\u002Fcommon\u002Fapi.yaml#\u002Fcomponents\u002Fschemas\u002FUser) into a Go type: unrecognized external reference '..\u002Fcommon\u002Fapi.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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002FURL that is $ref'd, point `oapi-codegen` to the Go package that this spec is generated into, to perform Go package imports\n  ..\u002Fcommon\u002Fapi.yaml: github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fexamples\u002Fimport-mapping\u002Fcommon\n```\n\nThis will then generate the following code:\n\n```go\npackage admin\n\nimport (\n\t\u002F\u002F ...\n\texternalRef0 \"github.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fexamples\u002Fimport-mapping\u002Fcommon\"\n)\n\n\u002F\u002F 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:\u002F\u002Fwww.jvt.me\u002Fposts\u002F2022\u002F02\u002F10\u002Fbundle-openapi\u002F) into a single spec.\n\nCheck out [the import-mapping\u002Fmultiplepackages example](examples\u002Fimport-mapping\u002Fmultiplepackages\u002F) 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:\u002F\u002Fgithub.com\u002FOAI\u002FOverlay-Specification), which is a stable specification.\n\n> [!CAUTION]\n> Beware! Here (may) be dragons.\n>\n> The Overlay specification requires the use of JSON Path, which some users may find difficult to write and\u002For maintain.\n>\n> We still heavily recommend using Overlay functionality, but would like users to be aware of this.\n>\n> There is a [proposed modification to the specification](https:\u002F\u002Fgithub.com\u002FOAI\u002FOverlay-Specification\u002Fpull\u002F32) 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:\u002F\u002Fgithub.com\u002FOAI\u002FOverlay-Specification)\"\npaths:\n  \u002Fping:\n    get:\n      responses:\n        '200':\n          description: pet response\n          content:\n            application\u002Fjson:\n              schema:\n                $ref: '#\u002Fcomponents\u002Fschemas\u002FPong'\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      \u002Fping:\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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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\u002Foverlay\u002F) 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 && *S.Field == \"123\"`)\n\nAs of `oapi-codegen` [v2.1.0](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Freleases\u002Ftag\u002Fv2.1.0) it is now possible to represent this with the `nullable.Nullable` type from [our new library, oapi-codegen\u002Fnullable](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fnullable).\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    \u002F\u002F 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:\u002F\u002Fspec.openapis.org\u002Foas\u002Fv3.0.3#specification-extensions).\n\nThe following extensions are supported:\n\n| Extension | Description | Docs                                                                  |\n| --- | --- |-----------------------------------------------------------------------|\n| `x-go-type` \u002F `x-go-type-import` | Override the generated type definition (and optionally, add an import from another package) | [(docs)](docs\u002Fextensions.md#x-go-type--x-go-type-import)              |\n| `x-go-type-skip-optional-pointer` | Do not add a pointer type for optional fields in structs | [(docs)](docs\u002Fextensions.md#x-go-type-skip-optional-pointer)          |\n| `x-go-name` | Override the generated name of a field or a type | [(docs)](docs\u002Fextensions.md#x-go-name)                                |\n| `x-go-type-name` | Override the generated name of a type | [(docs)](docs\u002Fextensions.md#x-go-type-name)                           |\n| `x-omitempty` | Force the presence of the JSON tag `omitempty` on a field | [(docs)](docs\u002Fextensions.md#x-omitempty)                              |\n| `x-omitzero` | Force the presence of the JSON tag `omitzero` on a field | [(docs)](docs\u002Fextensions.md#x-omitzero)                               |\n| `x-go-json-ignore` | When (un)marshaling JSON, ignore field(s) | [(docs)](docs\u002Fextensions.md#x-go-json-ignore)                         |\n| `x-oapi-codegen-extra-tags` | Generate arbitrary struct tags to fields | [(docs)](docs\u002Fextensions.md#x-oapi-codegen-extra-tags)                |\n| `x-enum-varnames` \u002F `x-enumNames` | Override generated variable names for enum constants | [(docs)](docs\u002Fextensions.md#x-enum-varnames--x-enumnames)             |\n| `x-deprecated-reason` | Add a GoDoc deprecation warning to a type | [(docs)](docs\u002Fextensions.md#x-deprecated-reason)                      |\n| `x-order` | Explicitly order struct fields | [(docs)](docs\u002Fextensions.md#x-order)                                  |\n| `x-oapi-codegen-only-honour-go-name` | Only honour the `x-go-name` when generating field names | [(docs)](docs\u002Fextensions.md#x-oapi-codegen-only-honour-go-name)       |\n\n## Request\u002Fresponse 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>\n\n\u003Ctr>\n\u003Cth>\nServer\n\u003C\u002Fth>\n\u003Cth>\nMiddleware library\n\u003C\u002Fth>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[Chi](https:\u002F\u002Fgithub.com\u002Fgo-chi\u002Fchi)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[nethttp-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fnethttp-middleware)\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[Echo](https:\u002F\u002Fgithub.com\u002Flabstack\u002Fecho)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[echo-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fecho-middleware)\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[Fiber](https:\u002F\u002Fgithub.com\u002Fgofiber\u002Ffiber)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[fiber-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Ffiber-middleware)\n\n\u003C\u002Ftd>\n\n\u003C\u002Ftr>\n\n\n\u003Ctr>\n\u003Ctd>\n\n[Gin](https:\u002F\u002Fgithub.com\u002Fgin-gonic\u002Fgin)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[gin-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fgin-middleware)\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[gorilla\u002Fmux](https:\u002F\u002Fgithub.com\u002Fgorilla\u002Fmux)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[nethttp-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fnethttp-middleware)\n\n\u003C\u002Ftd>\n\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[Iris](https:\u002F\u002Fgithub.com\u002Fkataras\u002Firis)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[iris-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Firis-middleware)\n\n\u003C\u002Ftd>\n\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\n[`net\u002Fhttp`](https:\u002F\u002Fpkg.go.dev\u002Fnet\u002Fhttp)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[nethttp-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fnethttp-middleware)\n\n\u003C\u002Ftd>\n\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>\n\nAny other server (which conforms to `net\u002Fhttp`)\n\n\u003C\u002Ftd>\n\u003Ctd>\n\n[nethttp-middleware](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Fnethttp-middleware)\n\n\u003C\u002Ftd>\n\n\u003C\u002Ftr>\n\n\u003C\u002Ftable>\n\n> [!NOTE]\n> It is [not currently possible](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1038) to validate the HTTP response with a middleware.\n\n## Implementing security\n\nIf you're using a specification with [Security Schemes](https:\u002F\u002Fspec.openapis.org\u002Foas\u002Fv3.0.3#security-scheme-object) and [Security Requirements](https:\u002F\u002Fspec.openapis.org\u002Foas\u002Fv3.0.3#security-requirement-object), you'll want to authenticate and authorize requests.\n\n### On the server\n\n> [!NOTE]\n> Out-of-the-box, the server-side code generated by `oapi-codegen` does not provide security validation.\n>\n> To perform authentication, you will need to use the [validation middleware](#requestresponse-validation-middleware), which validates each request against the spec's security requirements and calls your `AuthenticationFunc` with the scheme name and required scopes.\n\nTo see how this can work, check out the [authenticated API example](examples\u002Fauthenticated-api\u002Fecho).\n\n#### Deprecated: auth scopes on the request context\n\nHistorically, generated server code embedded each operation's security scopes into the request context:\na context key type per security scheme (e.g. `bearerAuthContextKey`), a scope constant (e.g. `BearerAuthScopes`),\nand a per-operation call storing the operation's scopes into the request context.\n\nThis mechanism is deprecated and no longer generated by default. It flattens the\nspec's `security` requirements into a per-scheme list of scopes, and cannot represent\nalternative schemes (OR), combined schemes (AND), or anonymous (`{}`) alternatives, so middleware built on it can't correctly enforce the spec. Use the [validation middleware](#requestresponse-validation-middleware) instead. Please see [#1524](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1524) for more background.\n\nIf you have existing middleware that relies on these constants, you can re-enable them with:\n\n```yaml\ncompatibility:\n  enable-auth-scopes-on-context: true\n```\n\nNote that even when re-enabled, an operation that includes an empty `{}` security alternative allows anonymous requests, and no scopes are embedded into the request context for that operation.\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\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fpkg\u002Fsecurityprovider\"\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:\u002F\u002F....\", 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\u002Fsecurityprovider` package](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2\u002Fpkg\u002Fsecurityprovider), 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\u002Ftemplate`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> [!NOTE]\n> 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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-schema.json\n# ...\noutput-options:\n  user-templates:\n    client-with-responses.tmpl: .\u002Fcustom-template.tmpl\n    additional-properties.tmpl: \u002Ftmp\u002Ffoo.bar\n    typedef.tmpl: no-prefix.tmpl\n```\n\n> [!WARNING]\n> 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> [!WARNING]\n> 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>\n> See [this blog post](https:\u002F\u002Fwww.jvt.me\u002Fposts\u002F2024\u002F04\u002F27\u002Fgithub-actions-update-file\u002F) for an example of how to use GitHub Actions to manage the updates of files across repos\n>\n> See [this blog post](https:\u002F\u002Fwww.jvt.me\u002Fposts\u002F2026\u002F02\u002F27\u002Frenovate-update-file) for an example of how to use Renovate to manage the updates of files across repos\n>\n> This will be disabled by default (but possible to turn back on via configuration) [in the future](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1564)\n\nTo use it, you can use the following configuration:\n\n```yaml\n# yaml-language-server: $schema=https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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:\u002F\u002Fraw.githubusercontent.com\u002F\u003Cusername>\u002F\u003Cproject>\u002F\u003Ccommitish>\u002Fpath\u002Fto\u002Ftemplate\u002Ftemplate.tmpl\n\n    # Alternatively using raw.githubusercontent.com with a hash\n    client-with-responses.tmpl: https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fad5eada4f3ccc28a88477cef62ea21c17fc8aa01\u002Fpkg\u002Fcodegen\u002Ftemplates\u002Fclient-with-responses.tmpl\n    # Alternatively using raw.githubusercontent.com with a tag\n    client-with-responses.tmpl: https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.1.0\u002Fpkg\u002Fcodegen\u002Ftemplates\u002Fclient-with-responses.tmpl\n    # Alternatively using raw.githubusercontent.com with a branch\n    client-with-responses.tmpl: https:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fmaster\u002Fpkg\u002Fcodegen\u002Ftemplates\u002Fclient-with-responses.tmpl\n```\n\n> [!WARNING]\n> 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:\u002F\u002Fraw.githubusercontent.com\u002Foapi-codegen\u002Foapi-codegen\u002Fv2.8.0\u002Fconfiguration-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:\u002F\u002Fstackoverflow.com\u002Fa\u002F18708156\u002F2257038 and\n    # https:\u002F\u002Fstackoverflow.com\u002Fa\u002F15365296\u002F2257038\n    client-with-responses.tmpl: |\n        \u002F\u002F 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:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1487).\n\n## Additional Properties (`additionalProperties`)\n\n[OpenAPI Schemas](https:\u002F\u002Fspec.openapis.org\u002Foas\u002Fv3.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> [!NOTE]\n> In the future [this will be possible](https:\u002F\u002Fgithub.com\u002Foapi-codegen\u002Foapi-codegen\u002Fissues\u002F1514) 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` \u002F 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\u002F\u002F Thing defines model for Thing.\ntype Thing struct {\n\tId int `json:\"id\"`\n}\n\n\u002F\u002F 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\u002F\u002F Thing defines model for Thing.\ntype Thing struct {\n\tId                   int                    `json:\"id\"`\n\tAdditionalProperties map[string]interface{} `json:\"-\"`\n}\n\n\u002F\u002F with generated boilerplate below\n```\n\n\u003Cdetails>\n\n\u003Csummary>Boilerplate\u003C\u002Fsummary>\n\n```go\n\n\u002F\u002F Getter for additional properties for Thing. Returns the specified\n\u002F\u002F 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\u002F\u002F 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\u002F\u002F 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, &object)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif raw, found := object[\"id\"]; found {\n\t\terr = json.Unmarshal(raw, &a.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, &fieldVal)\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\u002F\u002F 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\u002Fdetails>\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\u002F\u002F Thing defines model for Thing.\ntype Thing struct {\n\tId                   int            `json:\"id\"`\n\tAdditionalProperties map[string]int `json:\"-\"`\n}\n\n\u002F\u002F with generated boilerplate below\n```\n\n\u003Cdetails>\n\n\u003Csummary>Boilerplate\u003C\u002Fsummary>\n\n```go\n\u002F\u002F Getter for additional properties for Thing. Returns the specified\n\u002F\u002F 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\u002F\u002F 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\u002F\u002F 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, &object)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif raw, found := object[\"id\"]; found {\n\t\terr = json.Unmarshal(raw, &a.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, &fieldVal)\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\u002F\u002F 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(objec","2026-07-20 02:30:05","trending"]