Repository: deepmap/oapi-codegen
Pull request #809 (2022-10-24 01:44:17)

Fix styling AnyOf issue


Patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..61bacce
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+version: 2
+updates:
+  - package-ecosystem: "gomod"
+    directory: "/"
+    schedule:
+      interval: "weekly"
diff --git a/README.md b/README.md
index ba45d6b..295edf3 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ type ServerInterface interface {
 These are the functions which you will implement yourself in order to create
 a server conforming to the API specification. Normally, all the arguments and
 parameters are stored on the `echo.Context` in handlers, so we do the tedious
-work of of unmarshaling the JSON automatically, simply passing values into
+work of unmarshalling the JSON automatically, simply passing values into
 your handlers.
 
 Notice that `FindPetById` takes a parameter `id int64`. All path arguments
diff --git a/examples/petstore-expanded/chi/api/petstore.gen.go b/examples/petstore-expanded/chi/api/petstore.gen.go
index 59e517c..66505c5 100644
--- a/examples/petstore-expanded/chi/api/petstore.gen.go
+++ b/examples/petstore-expanded/chi/api/petstore.gen.go
@@ -201,16 +201,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
 	return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
 	ParamName string
 	Err       error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-	return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
 	return e.Err
 }
 
diff --git a/examples/petstore-expanded/chi/api/petstore.go b/examples/petstore-expanded/chi/api/petstore.go
index 2b3dc97..838c961 100644
--- a/examples/petstore-expanded/chi/api/petstore.go
+++ b/examples/petstore-expanded/chi/api/petstore.go
@@ -28,7 +28,7 @@ func NewPetStore() *PetStore {
 
 // This function wraps sending of an error in the Error format, and
 // handling the failure to marshal that.
-func sendPetstoreError(w http.ResponseWriter, code int, message string) {
+func sendPetStoreError(w http.ResponseWriter, code int, message string) {
 	petErr := Error{
 		Code:    int32(code),
 		Message: message,
@@ -74,7 +74,7 @@ func (p *PetStore) AddPet(w http.ResponseWriter, r *http.Request) {
 	// We expect a NewPet object in the request body.
 	var newPet NewPet
 	if err := json.NewDecoder(r.Body).Decode(&newPet); err != nil {
-		sendPetstoreError(w, http.StatusBadRequest, "Invalid format for NewPet")
+		sendPetStoreError(w, http.StatusBadRequest, "Invalid format for NewPet")
 		return
 	}
 
@@ -105,7 +105,7 @@ func (p *PetStore) FindPetByID(w http.ResponseWriter, r *http.Request, id int64)
 
 	pet, found := p.Pets[id]
 	if !found {
-		sendPetstoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
+		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 		return
 	}
 
@@ -119,7 +119,7 @@ func (p *PetStore) DeletePet(w http.ResponseWriter, r *http.Request, id int64) {
 
 	_, found := p.Pets[id]
 	if !found {
-		sendPetstoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
+		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 		return
 	}
 	delete(p.Pets, id)
diff --git a/examples/petstore-expanded/echo/api/petstore.go b/examples/petstore-expanded/echo/api/petstore.go
index 70b696c..65229d0 100644
--- a/examples/petstore-expanded/echo/api/petstore.go
+++ b/examples/petstore-expanded/echo/api/petstore.go
@@ -41,7 +41,7 @@ func NewPetStore() *PetStore {
 
 // This function wraps sending of an error in the Error format, and
 // handling the failure to marshal that.
-func sendPetstoreError(ctx echo.Context, code int, message string) error {
+func sendPetStoreError(ctx echo.Context, code int, message string) error {
 	petErr := models.Error{
 		Code:    int32(code),
 		Message: message,
@@ -86,7 +86,7 @@ func (p *PetStore) AddPet(ctx echo.Context) error {
 	var newPet models.NewPet
 	err := ctx.Bind(&newPet)
 	if err != nil {
-		return sendPetstoreError(ctx, http.StatusBadRequest, "Invalid format for NewPet")
+		return sendPetStoreError(ctx, http.StatusBadRequest, "Invalid format for NewPet")
 	}
 	// We now have a pet, let's add it to our "database".
 
@@ -126,7 +126,7 @@ func (p *PetStore) FindPetByID(ctx echo.Context, petId int64) error {
 
 	pet, found := p.Pets[petId]
 	if !found {
-		return sendPetstoreError(ctx, http.StatusNotFound,
+		return sendPetStoreError(ctx, http.StatusNotFound,
 			fmt.Sprintf("Could not find pet with ID %d", petId))
 	}
 	return ctx.JSON(http.StatusOK, pet)
@@ -138,7 +138,7 @@ func (p *PetStore) DeletePet(ctx echo.Context, id int64) error {
 
 	_, found := p.Pets[id]
 	if !found {
-		return sendPetstoreError(ctx, http.StatusNotFound,
+		return sendPetStoreError(ctx, http.StatusNotFound,
 			fmt.Sprintf("Could not find pet with ID %d", id))
 	}
 	delete(p.Pets, id)
diff --git a/examples/petstore-expanded/gin/api/petstore-server.gen.go b/examples/petstore-expanded/gin/api/petstore-server.gen.go
index b05b843..8dabdd9 100644
--- a/examples/petstore-expanded/gin/api/petstore-server.gen.go
+++ b/examples/petstore-expanded/gin/api/petstore-server.gen.go
@@ -38,6 +38,7 @@ type ServerInterface interface {
 type ServerInterfaceWrapper struct {
 	Handler            ServerInterface
 	HandlerMiddlewares []MiddlewareFunc
+	ErrorHandler       func(*gin.Context, error, int)
 }
 
 type MiddlewareFunc func(c *gin.Context)
@@ -54,7 +55,7 @@ func (siw *ServerInterfaceWrapper) FindPets(c *gin.Context) {
 
 	err = runtime.BindQueryParameter("form", true, false, "tags", c.Request.URL.Query(), &params.Tags)
 	if err != nil {
-		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter tags: %s", err)})
+		siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter tags: %s", err), http.StatusBadRequest)
 		return
 	}
 
@@ -62,7 +63,7 @@ func (siw *ServerInterfaceWrapper) FindPets(c *gin.Context) {
 
 	err = runtime.BindQueryParameter("form", true, false, "limit", c.Request.URL.Query(), &params.Limit)
 	if err != nil {
-		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter limit: %s", err)})
+		siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter limit: %s", err), http.StatusBadRequest)
 		return
 	}
 
@@ -93,7 +94,7 @@ func (siw *ServerInterfaceWrapper) DeletePet(c *gin.Context) {
 
 	err = runtime.BindStyledParameter("simple", false, "id", c.Param("id"), &id)
 	if err != nil {
-		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter id: %s", err)})
+		siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %s", err), http.StatusBadRequest)
 		return
 	}
 
@@ -114,7 +115,7 @@ func (siw *ServerInterfaceWrapper) FindPetByID(c *gin.Context) {
 
 	err = runtime.BindStyledParameter("simple", false, "id", c.Param("id"), &id)
 	if err != nil {
-		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter id: %s", err)})
+		siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %s", err), http.StatusBadRequest)
 		return
 	}
 
@@ -127,8 +128,9 @@ func (siw *ServerInterfaceWrapper) FindPetByID(c *gin.Context) {
 
 // GinServerOptions provides options for the Gin server.
 type GinServerOptions struct {
-	BaseURL     string
-	Middlewares []MiddlewareFunc
+	BaseURL      string
+	Middlewares  []MiddlewareFunc
+	ErrorHandler func(*gin.Context, error, int)
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
@@ -138,9 +140,19 @@ func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
 func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
+
+	errorHandler := options.ErrorHandler
+
+	if errorHandler == nil {
+		errorHandler = func(c *gin.Context, err error, statusCode int) {
+			c.JSON(statusCode, gin.H{"msg": err.Error()})
+		}
+	}
+
 	wrapper := ServerInterfaceWrapper{
 		Handler:            si,
 		HandlerMiddlewares: options.Middlewares,
+		ErrorHandler:       errorHandler,
 	}
 
 	router.GET(options.BaseURL+"/pets", wrapper.FindPets)
diff --git a/examples/petstore-expanded/gin/api/petstore.go b/examples/petstore-expanded/gin/api/petstore.go
index f79d282..2654d37 100644
--- a/examples/petstore-expanded/gin/api/petstore.go
+++ b/examples/petstore-expanded/gin/api/petstore.go
@@ -40,7 +40,7 @@ func NewPetStore() *PetStore {
 
 // This function wraps sending of an error in the Error format, and
 // handling the failure to marshal that.
-func sendPetstoreError(c *gin.Context, code int, message string) {
+func sendPetStoreError(c *gin.Context, code int, message string) {
 	petErr := Error{
 		Code:    int32(code),
 		Message: message,
@@ -84,7 +84,7 @@ func (p *PetStore) AddPet(c *gin.Context) {
 	var newPet NewPet
 	err := c.Bind(&newPet)
 	if err != nil {
-		sendPetstoreError(c, http.StatusBadRequest, "Invalid format for NewPet")
+		sendPetStoreError(c, http.StatusBadRequest, "Invalid format for NewPet")
 		return
 	}
 	// We now have a pet, let's add it to our "database".
@@ -114,7 +114,7 @@ func (p *PetStore) FindPetByID(c *gin.Context, petId int64) {
 
 	pet, found := p.Pets[petId]
 	if !found {
-		sendPetstoreError(c, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", petId))
+		sendPetStoreError(c, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", petId))
 		return
 	}
 	c.JSON(http.StatusOK, pet)
@@ -126,7 +126,7 @@ func (p *PetStore) DeletePet(c *gin.Context, id int64) {
 
 	_, found := p.Pets[id]
 	if !found {
-		sendPetstoreError(c, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
+		sendPetStoreError(c, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 	}
 	delete(p.Pets, id)
 	c.Status(http.StatusNoContent)
diff --git a/examples/petstore-expanded/gorilla/api/petstore.gen.go b/examples/petstore-expanded/gorilla/api/petstore.gen.go
index b56e03c..deac982 100644
--- a/examples/petstore-expanded/gorilla/api/petstore.gen.go
+++ b/examples/petstore-expanded/gorilla/api/petstore.gen.go
@@ -201,16 +201,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
 	return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
 	ParamName string
 	Err       error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-	return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
 	return e.Err
 }
 
diff --git a/examples/petstore-expanded/gorilla/api/petstore.go b/examples/petstore-expanded/gorilla/api/petstore.go
index 2b3dc97..838c961 100644
--- a/examples/petstore-expanded/gorilla/api/petstore.go
+++ b/examples/petstore-expanded/gorilla/api/petstore.go
@@ -28,7 +28,7 @@ func NewPetStore() *PetStore {
 
 // This function wraps sending of an error in the Error format, and
 // handling the failure to marshal that.
-func sendPetstoreError(w http.ResponseWriter, code int, message string) {
+func sendPetStoreError(w http.ResponseWriter, code int, message string) {
 	petErr := Error{
 		Code:    int32(code),
 		Message: message,
@@ -74,7 +74,7 @@ func (p *PetStore) AddPet(w http.ResponseWriter, r *http.Request) {
 	// We expect a NewPet object in the request body.
 	var newPet NewPet
 	if err := json.NewDecoder(r.Body).Decode(&newPet); err != nil {
-		sendPetstoreError(w, http.StatusBadRequest, "Invalid format for NewPet")
+		sendPetStoreError(w, http.StatusBadRequest, "Invalid format for NewPet")
 		return
 	}
 
@@ -105,7 +105,7 @@ func (p *PetStore) FindPetByID(w http.ResponseWriter, r *http.Request, id int64)
 
 	pet, found := p.Pets[id]
 	if !found {
-		sendPetstoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
+		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 		return
 	}
 
@@ -119,7 +119,7 @@ func (p *PetStore) DeletePet(w http.ResponseWriter, r *http.Request, id int64) {
 
 	_, found := p.Pets[id]
 	if !found {
-		sendPetstoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
+		sendPetStoreError(w, http.StatusNotFound, fmt.Sprintf("Could not find pet with ID %d", id))
 		return
 	}
 	delete(p.Pets, id)
diff --git a/examples/petstore-expanded/strict/api/petstore-server.gen.go b/examples/petstore-expanded/strict/api/petstore-server.gen.go
index 8901ebb..cd9352a 100644
--- a/examples/petstore-expanded/strict/api/petstore-server.gen.go
+++ b/examples/petstore-expanded/strict/api/petstore-server.gen.go
@@ -161,16 +161,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
 	return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
 	ParamName string
 	Err       error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-	return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
 	return e.Err
 }
 
diff --git a/go.mod b/go.mod
index c06974e..9dcd51f 100644
--- a/go.mod
+++ b/go.mod
@@ -2,17 +2,17 @@ module github.com/deepmap/oapi-codegen
 
 require (
 	github.com/apapsch/go-jsonmerge/v2 v2.0.0
-	github.com/getkin/kin-openapi v0.104.0
+	github.com/getkin/kin-openapi v0.107.0
 	github.com/gin-gonic/gin v1.8.1
 	github.com/go-chi/chi/v5 v5.0.7
 	github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219
 	github.com/google/uuid v1.3.0
 	github.com/gorilla/mux v1.8.0
-	github.com/labstack/echo/v4 v4.9.0
+	github.com/labstack/echo/v4 v4.9.1
 	github.com/lestrrat-go/jwx v1.2.25
 	github.com/matryer/moq v0.2.7
-	github.com/stretchr/testify v1.8.0
-	golang.org/x/tools v0.1.12
+	github.com/stretchr/testify v1.8.1
+	golang.org/x/tools v0.2.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -24,13 +24,13 @@ require (
 	github.com/go-openapi/swag v0.21.1 // indirect
 	github.com/go-playground/locales v0.14.0 // indirect
 	github.com/go-playground/universal-translator v0.18.0 // indirect
-	github.com/go-playground/validator/v10 v10.11.0 // indirect
-	github.com/goccy/go-json v0.9.7 // indirect
+	github.com/go-playground/validator/v10 v10.11.1 // indirect
+	github.com/goccy/go-json v0.9.11 // indirect
 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
 	github.com/invopop/yaml v0.1.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/labstack/gommon v0.3.1 // indirect
+	github.com/labstack/gommon v0.4.0 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
 	github.com/lestrrat-go/blackmagic v1.0.0 // indirect
@@ -38,26 +38,26 @@ require (
 	github.com/lestrrat-go/iter v1.0.1 // indirect
 	github.com/lestrrat-go/option v1.0.0 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
-	github.com/mattn/go-colorable v0.1.12 // indirect
-	github.com/mattn/go-isatty v0.0.14 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.16 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.5 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/stretchr/objx v0.4.0 // indirect
+	github.com/stretchr/objx v0.5.0 // indirect
 	github.com/ugorji/go/codec v1.2.7 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
-	github.com/valyala/fasttemplate v1.2.1 // indirect
-	golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 // indirect
-	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
-	golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
-	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
-	golang.org/x/text v0.3.7 // indirect
+	github.com/valyala/fasttemplate v1.2.2 // indirect
+	golang.org/x/crypto v0.1.0 // indirect
+	golang.org/x/mod v0.6.0 // indirect
+	golang.org/x/net v0.1.0 // indirect
+	golang.org/x/sys v0.1.0 // indirect
+	golang.org/x/text v0.4.0 // indirect
 	golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
 	golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
-	google.golang.org/protobuf v1.28.0 // indirect
+	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
diff --git a/go.sum b/go.sum
index ad12a43..c8c1e6b 100644
--- a/go.sum
+++ b/go.sum
@@ -10,8 +10,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
-github.com/getkin/kin-openapi v0.104.0 h1:DZ2F89M/nnjgmIq08Fr/rxmtHmC9A0RVqFWr/ZPdYf4=
-github.com/getkin/kin-openapi v0.104.0/go.mod h1:9Dhr+FasATJZjS4iOLvB0hkaxgYdulrNYm2e9epLWOo=
+github.com/getkin/kin-openapi v0.107.0 h1:bxhL6QArW7BXQj8NjXfIJQy680NsMKd25nwhvpCXchg=
+github.com/getkin/kin-openapi v0.107.0/go.mod h1:9Dhr+FasATJZjS4iOLvB0hkaxgYdulrNYm2e9epLWOo=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
@@ -29,10 +29,11 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
 github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
 github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
 github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
-github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
-github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
-github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
+github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
+github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
+github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
 github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -60,10 +61,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
-github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
-github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
-github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
+github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
+github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
+github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
+github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
 github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
 github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
 github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
@@ -86,10 +87,11 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
 github.com/matryer/moq v0.2.7 h1:RtpiPUM8L7ZSCbSwK+QcZH/E9tgqAkFjKQxsRs25b4w=
 github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
 github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
-github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
-github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -98,8 +100,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
-github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
+github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -110,38 +112,41 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
 github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
 github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
 github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
+github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 h1:NUzdAbFtCJSXU20AOXgeqaUwg8Ypg4MPYmL+d+rsB5c=
-golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -153,21 +158,23 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
 golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -175,8 +182,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/pkg/codegen/inline.go b/pkg/codegen/inline.go
index eedafa7..e722337 100644
--- a/pkg/codegen/inline.go
+++ b/pkg/codegen/inline.go
@@ -16,6 +16,7 @@ package codegen
 import (
 	"bytes"
 	"compress/gzip"
+	"context"
 	"encoding/base64"
 	"fmt"
 	"text/template"
@@ -26,6 +27,8 @@ import (
 // GenerateInlinedSpec generates a gzipped, base64 encoded JSON representation of the
 // swagger definition, which we embed inside the generated code.
 func GenerateInlinedSpec(t *template.Template, importMapping importMap, swagger *openapi3.T) (string, error) {
+	// ensure that any external file references are embedded into the embedded spec
+	swagger.InternalizeRefs(context.Background(), nil)
 	// Marshal to json
 	encoded, err := swagger.MarshalJSON()
 	if err != nil {
diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go
index ff1ea9c..314e894 100644
--- a/pkg/codegen/operations.go
+++ b/pkg/codegen/operations.go
@@ -510,10 +510,10 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) {
 					return nil, fmt.Errorf("error generating default OperationID for %s/%s: %s",
 						opName, requestPath, err)
 				}
-				op.OperationID = op.OperationID
 			} else {
 				op.OperationID = ToCamelCase(op.OperationID)
 			}
+			op.OperationID = typeNamePrefix(op.OperationID) + op.OperationID
 
 			// These are parameters defined for the specific path method that
 			// we're iterating over.
@@ -934,7 +934,7 @@ func GenerateClient(t *template.Template, ops []OperationDefinition) (string, er
 }
 
 // GenerateClientWithResponses generates a client which extends the basic client which does response
-// unmarshaling.
+// unmarshalling.
 func GenerateClientWithResponses(t *template.Template, ops []OperationDefinition) (string, error) {
 	return GenerateTemplates([]string{"client-with-responses.tmpl"}, t, ops)
 }
diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go
index 8254cd8..0dacb92 100644
--- a/pkg/codegen/schema.go
+++ b/pkg/codegen/schema.go
@@ -166,7 +166,7 @@ type TypeDefinition struct {
 }
 
 // ResponseTypeDefinition is an extension of TypeDefinition, specifically for
-// response unmarshaling in ClientWithResponses.
+// response unmarshalling in ClientWithResponses.
 type ResponseTypeDefinition struct {
 	TypeDefinition
 	// The content type name where this is used, eg, application/json
diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go
index 746c457..54b42db 100644
--- a/pkg/codegen/template_helpers.go
+++ b/pkg/codegen/template_helpers.go
@@ -95,7 +95,7 @@ func genResponsePayload(operationID string) string {
 	return buffer.String()
 }
 
-// genResponseUnmarshal generates unmarshaling steps for structured response payloads
+// genResponseUnmarshal generates unmarshalling steps for structured response payloads
 func genResponseUnmarshal(op *OperationDefinition) string {
 	var handledCaseClauses = make(map[string]string)
 	var unhandledCaseClauses = make(map[string]string)
@@ -127,7 +127,7 @@ func genResponseUnmarshal(op *OperationDefinition) string {
 			continue
 		}
 
-		// If there is no content-type then we have no unmarshaling to do:
+		// If there is no content-type then we have no unmarshalling to do:
 		if len(responseRef.Value.Content) == 0 {
 			caseAction := "break // No content-type"
 			caseClauseKey := "case " + getConditionOfResponseName("rsp.StatusCode", typeDefinition.ResponseName) + ":"
@@ -135,7 +135,7 @@ func genResponseUnmarshal(op *OperationDefinition) string {
 			continue
 		}
 
-		// If we made it this far then we need to handle unmarshaling for each content-type:
+		// If we made it this far then we need to handle unmarshalling for each content-type:
 		sortedContentKeys := SortedContentKeys(responseRef.Value.Content)
 		for _, contentTypeName := range sortedContentKeys {
 
diff --git a/pkg/codegen/templates/additional-properties.tmpl b/pkg/codegen/templates/additional-properties.tmpl
index 46b66c8..8a37647 100644
--- a/pkg/codegen/templates/additional-properties.tmpl
+++ b/pkg/codegen/templates/additional-properties.tmpl
@@ -39,7 +39,7 @@ func (a *{{.TypeName}}) UnmarshalJSON(b []byte) error {
             var fieldVal {{$addType}}
             err := json.Unmarshal(fieldBuf, &fieldVal)
             if err != nil {
-                return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+                return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
             }
             a.AdditionalProperties[fieldName] = fieldVal
         }
diff --git a/pkg/codegen/templates/chi/chi-middleware.tmpl b/pkg/codegen/templates/chi/chi-middleware.tmpl
index 77a5c2a..bb4e8f7 100644
--- a/pkg/codegen/templates/chi/chi-middleware.tmpl
+++ b/pkg/codegen/templates/chi/chi-middleware.tmpl
@@ -25,7 +25,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
   {{if .IsJson}}
   err = json.Unmarshal([]byte(chi.URLParam(r, "{{.ParamName}}")), &{{$varName}})
   if err != nil {
-    siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+    siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
     return
   }
   {{end}}
@@ -62,7 +62,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
           var value {{.TypeDef}}
           err = json.Unmarshal([]byte(paramValue), &value)
           if err != nil {
-            siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+            siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
             return
           }
 
@@ -101,7 +101,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
         {{if .IsJson}}
           err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}})
           if err != nil {
-            siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+            siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
             return
           }
         {{end}}
@@ -146,7 +146,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
 
         err = json.Unmarshal([]byte(decoded), &value)
         if err != nil {
-          siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+          siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
           return
         }
 
@@ -204,16 +204,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
     return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
     ParamName string
     Err error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-    return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+    return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
     return e.Err
 }
 
diff --git a/pkg/codegen/templates/echo/echo-wrappers.tmpl b/pkg/codegen/templates/echo/echo-wrappers.tmpl
index 3402583..f2e4dbc 100644
--- a/pkg/codegen/templates/echo/echo-wrappers.tmpl
+++ b/pkg/codegen/templates/echo/echo-wrappers.tmpl
@@ -14,7 +14,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error {
 {{if .IsJson}}
     err = json.Unmarshal([]byte(ctx.Param("{{.ParamName}}")), &{{$varName}})
     if err != nil {
-        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON")
+        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter '{{.ParamName}}' as JSON")
     }
 {{end}}
 {{if .IsStyled}}
@@ -50,7 +50,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error {
     var value {{.TypeDef}}
     err = json.Unmarshal([]byte(paramValue), &value)
     if err != nil {
-        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON")
+        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter '{{.ParamName}}' as JSON")
     }
     params.{{.GoName}} = {{if not .Required}}&{{end}}value
     {{end}}
@@ -75,7 +75,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error {
 {{if .IsJson}}
         err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}})
         if err != nil {
-            return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON")
+            return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter '{{.ParamName}}' as JSON")
         }
 {{end}}
 {{if .IsStyled}}
@@ -105,7 +105,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error {
     }
     err = json.Unmarshal([]byte(decoded), &value)
     if err != nil {
-        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON")
+        return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter '{{.ParamName}}' as JSON")
     }
     params.{{.GoName}} = {{if not .Required}}&{{end}}value
     {{end}}
diff --git a/pkg/codegen/templates/gin/gin-register.tmpl b/pkg/codegen/templates/gin/gin-register.tmpl
index 5362dd7..188cbb8 100644
--- a/pkg/codegen/templates/gin/gin-register.tmpl
+++ b/pkg/codegen/templates/gin/gin-register.tmpl
@@ -2,6 +2,7 @@
 type GinServerOptions struct {
     BaseURL string
     Middlewares []MiddlewareFunc
+    ErrorHandler func(*gin.Context, error, int)
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
@@ -11,13 +12,23 @@ func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
 func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
-{{if .}}wrapper := ServerInterfaceWrapper{
-Handler: si,
-HandlerMiddlewares: options.Middlewares,
-}
-{{end}}
-{{range .}}
-router.{{.Method }}(options.BaseURL+"{{.Path | swaggerUriToGinUri }}", wrapper.{{.OperationId}})
-{{end}}
-return router
+    {{if .}}
+    errorHandler := options.ErrorHandler
+
+    if errorHandler == nil {
+        errorHandler = func(c *gin.Context, err error, statusCode int) {
+            c.JSON(statusCode, gin.H{"msg": err.Error()})
+        }
+    }
+
+    wrapper := ServerInterfaceWrapper{
+        Handler: si,
+        HandlerMiddlewares: options.Middlewares,
+        ErrorHandler: errorHandler,
+    }
+    {{end}}
+    {{range .}}
+    router.{{.Method }}(options.BaseURL+"{{.Path | swaggerUriToGinUri }}", wrapper.{{.OperationId}})
+    {{end}}
+    return router
 }
diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl
index 59d03f5..3c11bcd 100644
--- a/pkg/codegen/templates/gin/gin-wrappers.tmpl
+++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl
@@ -2,6 +2,7 @@
 type ServerInterfaceWrapper struct {
     Handler ServerInterface
     HandlerMiddlewares []MiddlewareFunc
+    ErrorHandler func(*gin.Context, error, int)
 }
 
 type MiddlewareFunc func(c *gin.Context)
@@ -24,14 +25,14 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
   {{if .IsJson}}
   err = json.Unmarshal([]byte(c.Query("{{.ParamName}}")), &{{$varName}})
   if err != nil {
-    c.JSON(http.StatusBadRequest, gin.H{"msg": "Error unmarshaling parameter '{{.ParamName}}' as JSON"})
+    siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON"), http.StatusBadRequest)
     return
   }
   {{end}}
   {{if .IsStyled}}
   err = runtime.BindStyledParameter("{{.Style}}",{{.Explode}}, "{{.ParamName}}", c.Param("{{.ParamName}}"), &{{$varName}})
   if err != nil {
-    c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)})
+    siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %s", err), http.StatusBadRequest)
     return
   }
   {{end}}
@@ -61,21 +62,23 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
           var value {{.TypeDef}}
           err = json.Unmarshal([]byte(paramValue), &value)
           if err != nil {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": "Error unmarshaling parameter '{{.ParamName}}' as JSON"})
+            siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON: %s", err), http.StatusBadRequest) {
             return
           }
 
           params.{{.GoName}} = {{if not .Required}}&{{end}}value
         {{end}}
         }{{if .Required}} else {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": "Query argument {{.ParamName}} is required, but not found"})
-            return
+           if !siw.ErrorHandler(c, fmt.Errorf("Query argument {{.ParamName}} is required, but not found: %s", err), http.StatusBadRequest) {
+             return
+           }
         }{{end}}
       {{end}}
+
       {{if .IsStyled}}
       err = runtime.BindQueryParameter("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", c.Request.URL.Query(), &params.{{.GoName}})
       if err != nil {
-        c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)})
+        siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %s", err), http.StatusBadRequest)
         return
       }
       {{end}}
@@ -89,7 +92,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
           var {{.GoName}} {{.TypeDef}}
           n := len(valueList)
           if n != 1 {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Expected one value for {{.ParamName}}, got %d", n)})
+            siw.ErrorHandler(c, fmt.Errorf("Expected one value for {{.ParamName}}, got %d", n), http.StatusBadRequest)
             return
           }
 
@@ -100,7 +103,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
         {{if .IsJson}}
           err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}})
           if err != nil {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": "Error unmarshaling parameter '{{.ParamName}}' as JSON"})
+            siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON"), http.StatusBadRequest)
             return
           }
         {{end}}
@@ -108,7 +111,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
         {{if .IsStyled}}
           err = runtime.BindStyledParameterWithLocation("{{.Style}}",{{.Explode}}, "{{.ParamName}}", runtime.ParamLocationHeader, valueList[0], &{{.GoName}})
           if err != nil {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)})
+            siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %s", err), http.StatusBadRequest)
             return
           }
         {{end}}
@@ -116,7 +119,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
           params.{{.GoName}} = {{if not .Required}}&{{end}}{{.GoName}}
 
         } {{if .Required}}else {
-            c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Header parameter {{.ParamName}} is required, but not found: %s", err)})
+            siw.ErrorHandler(c, fmt.Errorf("Header parameter {{.ParamName}} is required, but not found: %s", err), http.StatusBadRequest)
             return
         }{{end}}
 
@@ -137,14 +140,14 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
         var decoded string
         decoded, err := url.QueryUnescape(cookie.Value)
         if err != nil {
-          c.JSON(http.StatusBadRequest, gin.H{"msg": "Error unescaping cookie parameter '{{.ParamName}}'"})
-          return
+            siw.ErrorHandler(c, fmt.Errorf("Error unescaping cookie parameter '{{.ParamName}}'"), http.StatusBadRequest)
+            return
         }
 
         err = json.Unmarshal([]byte(decoded), &value)
         if err != nil {
-          c.JSON(http.StatusBadRequest, gin.H{"msg": "Error unmarshaling parameter '{{.ParamName}}' as JSON"})
-          return
+            siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON"), http.StatusBadRequest)
+            return
         }
 
         params.{{.GoName}} = {{if not .Required}}&{{end}}value
@@ -154,8 +157,8 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
         var value {{.TypeDef}}
         err = runtime.BindStyledParameter("simple",{{.Explode}}, "{{.ParamName}}", cookie.Value, &value)
         if err != nil {
-          c.JSON(http.StatusBadRequest, gin.H{"msg": "Invalid format for parameter {{.ParamName}}: %s"})
-          return
+            siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %s", err), http.StatusBadRequest)
+            return
         }
         params.{{.GoName}} = {{if not .Required}}&{{end}}value
       {{end}}
@@ -163,7 +166,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
       }
 
       {{- if .Required}} else {
-        c.JSON(http.StatusBadRequest, gin.H{"msg": "Query argument {{.ParamName}} is required, but not found"})
+        siw.ErrorHandler(c, fmt.Errorf("Query argument {{.ParamName}} is required, but not found"), http.StatusBadRequest)
         return
       }
       {{- end}}
diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
index d660a0b..a72713b 100644
--- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
+++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
@@ -25,7 +25,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
   {{if .IsJson}}
   err = json.Unmarshal([]byte(mux.Vars(r)["{{.ParamName}}"]), &{{$varName}})
   if err != nil {
-    siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+    siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
     return
   }
   {{end}}
@@ -62,7 +62,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
           var value {{.TypeDef}}
           err = json.Unmarshal([]byte(paramValue), &value)
           if err != nil {
-            siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+            siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
             return
           }
 
@@ -101,7 +101,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
         {{if .IsJson}}
           err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}})
           if err != nil {
-            siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+            siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
             return
           }
         {{end}}
@@ -146,7 +146,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
 
         err = json.Unmarshal([]byte(decoded), &value)
         if err != nil {
-          siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err})
+          siw.ErrorHandlerFunc(w, r, &UnmarshallingParamError{ParamName: "{{.ParamName}}", Err: err})
           return
         }
 
@@ -198,16 +198,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
     return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
     ParamName string
     Err error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-    return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+    return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
     return e.Err
 }
 
diff --git a/pkg/codegen/templates/union.tmpl b/pkg/codegen/templates/union.tmpl
index eb015be..b758a82 100644
--- a/pkg/codegen/templates/union.tmpl
+++ b/pkg/codegen/templates/union.tmpl
@@ -100,10 +100,12 @@
               }
             }
             {{range .Schema.Properties}}
+            {{if not .Required}}if t.{{.GoFieldName}} != nil { {{end}}
                 object["{{.JsonFieldName}}"], err = json.Marshal(t.{{.GoFieldName}})
                 if err != nil {
                     return nil, fmt.Errorf("error marshaling '{{.JsonFieldName}}': %w", err)
                 }
+            {{if not .Required}} }{{end}}
             {{end -}}
             b, err = json.Marshal(object)
         {{end -}}
diff --git a/pkg/runtime/bindparam.go b/pkg/runtime/bindparam.go
index 13d8706..4fc1b30 100644
--- a/pkg/runtime/bindparam.go
+++ b/pkg/runtime/bindparam.go
@@ -68,7 +68,7 @@ func BindStyledParameterWithLocation(style string, explode bool, paramName strin
 	// If the destination implements encoding.TextUnmarshaler we use it for binding
 	if tu, ok := dest.(encoding.TextUnmarshaler); ok {
 		if err := tu.UnmarshalText([]byte(value)); err != nil {
-			return fmt.Errorf("error unmarshaling '%s' text as %T: %s", value, dest, err)
+			return fmt.Errorf("error unmarshalling '%s' text as %T: %s", value, dest, err)
 		}
 
 		return nil
@@ -82,7 +82,7 @@ func BindStyledParameterWithLocation(style string, explode bool, paramName strin
 
 	if t.Kind() == reflect.Struct {
 		// We've got a destination object, we'll create a JSON representation
-		// of the input value, and let the json library deal with the unmarshaling
+		// of the input value, and let the json library deal with the unmarshalling
 		parts, err := splitStyledParameter(style, explode, true, paramName, value)
 		if err != nil {
 			return err
@@ -233,7 +233,7 @@ func bindSplitPartsToDestinationArray(parts []string, dest interface{}) error {
 // into the struct.
 func bindSplitPartsToDestinationStruct(paramName string, parts []string, explode bool, dest interface{}) error {
 	// We've got a destination object, we'll create a JSON representation
-	// of the input value, and let the json library deal with the unmarshaling
+	// of the input value, and let the json library deal with the unmarshalling
 	var fields []string
 	if explode {
 		fields = make([]string, len(parts))
@@ -462,7 +462,7 @@ func bindParamsToExplodedObject(paramName string, values url.Values, dest interf
 		return true, BindStringToObject(values.Get(paramName), dest)
 	}
 	if t.Kind() != reflect.Struct {
-		return false, fmt.Errorf("unmarshaling query arg '%s' into wrong type", paramName)
+		return false, fmt.Errorf("unmarshalling query arg '%s' into wrong type", paramName)
 	}
 
 	fieldsPresent := false
diff --git a/pkg/runtime/bindstring.go b/pkg/runtime/bindstring.go
index e106b5a..72f74dd 100644
--- a/pkg/runtime/bindstring.go
+++ b/pkg/runtime/bindstring.go
@@ -100,7 +100,7 @@ func BindStringToObject(src string, dst interface{}) error {
 	case reflect.Array:
 		if tu, ok := dst.(encoding.TextUnmarshaler); ok {
 			if err := tu.UnmarshalText([]byte(src)); err != nil {
-				return fmt.Errorf("error unmarshaling '%s' text as %T: %s", src, dst, err)
+				return fmt.Errorf("error unmarshalling '%s' text as %T: %s", src, dst, err)
 			}
 
 			return nil
diff --git a/pkg/runtime/styleparam.go b/pkg/runtime/styleparam.go
index 2ba86d9..8f7e129 100644
--- a/pkg/runtime/styleparam.go
+++ b/pkg/runtime/styleparam.go
@@ -14,7 +14,9 @@
 package runtime
 
 import (
+	"bytes"
 	"encoding"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"net/url"
@@ -222,6 +224,27 @@ func styleStruct(style string, explode bool, paramName string, paramLocation Par
 		return MarshalDeepObject(value, paramName)
 	}
 
+	// If input has Marshaler, such as object has Additional Property or AnyOf,
+	// We use this Marshaler and convert into interface{} before styling.
+	if m, ok := value.(json.Marshaler); ok {
+		buf, err := m.MarshalJSON()
+		if err != nil {
+			return "", fmt.Errorf("failed to marshal input to JSON: %w", err)
+		}
+		e := json.NewDecoder(bytes.NewReader(buf))
+		e.UseNumber()
+		var i2 interface{}
+		err = e.Decode(&i2)
+		if err != nil {
+			return "", fmt.Errorf("failed to unmarshal JSON: %w", err)
+		}
+		s, err := StyleParamWithLocation(style, explode, paramName, paramLocation, i2)
+		if err != nil {
+			return "", fmt.Errorf("error style JSON structure: %w", err)
+		}
+		return s, nil
+	}
+
 	// Otherwise, we need to build a dictionary of the struct's fields. Each
 	// field may only be a primitive value.
 	v := reflect.ValueOf(value)
@@ -402,6 +425,28 @@ func primitiveToString(value interface{}) (string, error) {
 		}
 	case reflect.String:
 		output = v.String()
+	case reflect.Struct:
+		// If input has Marshaler, such as object has Additional Property or AnyOf,
+		// We use this Marshaler and convert into interface{} before styling.
+		if m, ok := value.(json.Marshaler); ok {
+			buf, err := m.MarshalJSON()
+			if err != nil {
+				return "", fmt.Errorf("failed to marshal input to JSON: %w", err)
+			}
+			e := json.NewDecoder(bytes.NewReader(buf))
+			e.UseNumber()
+			var i2 interface{}
+			err = e.Decode(&i2)
+			if err != nil {
+				return "", fmt.Errorf("failed to unmarshal JSON: %w", err)
+			}
+			output, err = primitiveToString(i2)
+			if err != nil {
+				return "", fmt.Errorf("error convert JSON structure: %w", err)
+			}
+			break
+		}
+		fallthrough
 	default:
 		v, ok := value.(fmt.Stringer)
 		if !ok {


Test patch:
diff --git a/examples/petstore-expanded/chi/petstore_test.go b/examples/petstore-expanded/chi/petstore_test.go
index 5e36439..e0e9a88 100644
--- a/examples/petstore-expanded/chi/petstore_test.go
+++ b/examples/petstore-expanded/chi/petstore_test.go
@@ -53,7 +53,7 @@ func TestPetStore(t *testing.T) {
 
 		var resultPet api.Pet
 		err = json.NewDecoder(rr.Body).Decode(&resultPet)
-		assert.NoError(t, err, "error unmarshaling response")
+		assert.NoError(t, err, "error unmarshalling response")
 		assert.Equal(t, newPet.Name, resultPet.Name)
 		assert.Equal(t, *newPet.Tag, *resultPet.Tag)
 	})
@@ -146,7 +146,7 @@ func TestPetStore(t *testing.T) {
 
 		var petError api.Error
 		err = json.NewDecoder(rr.Body).Decode(&petError)
-		assert.NoError(t, err, "error unmarshaling PetError")
+		assert.NoError(t, err, "error unmarshalling PetError")
 		assert.Equal(t, int32(http.StatusNotFound), petError.Code)
 
 		// Now, delete both real pets
diff --git a/examples/petstore-expanded/echo/petstore_test.go b/examples/petstore-expanded/echo/petstore_test.go
index 36f5f42..b79d39d 100644
--- a/examples/petstore-expanded/echo/petstore_test.go
+++ b/examples/petstore-expanded/echo/petstore_test.go
@@ -72,7 +72,7 @@ func TestPetStore(t *testing.T) {
 	// sure that its fields match.
 	var resultPet models.Pet
 	err = result.UnmarshalBodyToObject(&resultPet)
-	assert.NoError(t, err, "error unmarshaling response")
+	assert.NoError(t, err, "error unmarshalling response")
 	assert.Equal(t, newPet.Name, resultPet.Name)
 	assert.Equal(t, *newPet.Tag, *resultPet.Tag)
 
@@ -106,7 +106,7 @@ func TestPetStore(t *testing.T) {
 	// We should have gotten a response from the server with the new pet. Make
 	// sure that its fields match.
 	err = result.UnmarshalBodyToObject(&resultPet)
-	assert.NoError(t, err, "error unmarshaling response")
+	assert.NoError(t, err, "error unmarshalling response")
 	petId2 := resultPet.Id
 
 	// Now, list all pets, we should have two
@@ -137,7 +137,7 @@ func TestPetStore(t *testing.T) {
 	result = testutil.NewRequest().Delete("/pets/7").Go(t, e)
 	assert.Equal(t, http.StatusNotFound, result.Code())
 	err = result.UnmarshalBodyToObject(&petError)
-	assert.NoError(t, err, "error unmarshaling PetError")
+	assert.NoError(t, err, "error unmarshalling PetError")
 	assert.Equal(t, int32(http.StatusNotFound), petError.Code)
 
 	// Now, delete both real pets
diff --git a/examples/petstore-expanded/gin/petstore_test.go b/examples/petstore-expanded/gin/petstore_test.go
index ccb38de..01fc944 100644
--- a/examples/petstore-expanded/gin/petstore_test.go
+++ b/examples/petstore-expanded/gin/petstore_test.go
@@ -35,7 +35,7 @@ func TestPetStore(t *testing.T) {
 
 		var resultPet api.Pet
 		err = json.NewDecoder(rr.Body).Decode(&resultPet)
-		assert.NoError(t, err, "error unmarshaling response")
+		assert.NoError(t, err, "error unmarshalling response")
 		assert.Equal(t, newPet.Name, resultPet.Name)
 		assert.Equal(t, *newPet.Tag, *resultPet.Tag)
 	})
@@ -119,7 +119,7 @@ func TestPetStore(t *testing.T) {
 
 		var petError api.Error
 		err = json.NewDecoder(rr.Body).Decode(&petError)
-		assert.NoError(t, err, "error unmarshaling PetError")
+		assert.NoError(t, err, "error unmarshalling PetError")
 		assert.Equal(t, int32(http.StatusNotFound), petError.Code)
 
 		// Now, delete both real pets
diff --git a/examples/petstore-expanded/gorilla/petstore_test.go b/examples/petstore-expanded/gorilla/petstore_test.go
index c60afbc..b0b52b3 100644
--- a/examples/petstore-expanded/gorilla/petstore_test.go
+++ b/examples/petstore-expanded/gorilla/petstore_test.go
@@ -53,7 +53,7 @@ func TestPetStore(t *testing.T) {
 
 		var resultPet api.Pet
 		err = json.NewDecoder(rr.Body).Decode(&resultPet)
-		assert.NoError(t, err, "error unmarshaling response")
+		assert.NoError(t, err, "error unmarshalling response")
 		assert.Equal(t, newPet.Name, resultPet.Name)
 		assert.Equal(t, *newPet.Tag, *resultPet.Tag)
 	})
@@ -146,7 +146,7 @@ func TestPetStore(t *testing.T) {
 
 		var petError api.Error
 		err = json.NewDecoder(rr.Body).Decode(&petError)
-		assert.NoError(t, err, "error unmarshaling PetError")
+		assert.NoError(t, err, "error unmarshalling PetError")
 		assert.Equal(t, int32(http.StatusNotFound), petError.Code)
 
 		// Now, delete both real pets
diff --git a/examples/petstore-expanded/strict/petstore_test.go b/examples/petstore-expanded/strict/petstore_test.go
index 34891e0..4cbfee0 100644
--- a/examples/petstore-expanded/strict/petstore_test.go
+++ b/examples/petstore-expanded/strict/petstore_test.go
@@ -53,7 +53,7 @@ func TestPetStore(t *testing.T) {
 
 		var resultPet api.Pet
 		err = json.NewDecoder(rr.Body).Decode(&resultPet)
-		assert.NoError(t, err, "error unmarshaling response")
+		assert.NoError(t, err, "error unmarshalling response")
 		assert.Equal(t, newPet.Name, resultPet.Name)
 		assert.Equal(t, *newPet.Tag, *resultPet.Tag)
 	})
@@ -146,7 +146,7 @@ func TestPetStore(t *testing.T) {
 
 		var petError api.Error
 		err = json.NewDecoder(rr.Body).Decode(&petError)
-		assert.NoError(t, err, "error unmarshaling PetError")
+		assert.NoError(t, err, "error unmarshalling PetError")
 		assert.Equal(t, int32(http.StatusNotFound), petError.Code)
 
 		// Now, delete both real pets
diff --git a/internal/test/any_of/param/config.yaml b/internal/test/any_of/param/config.yaml
new file mode 100644
index 0000000..7b28270
--- /dev/null
+++ b/internal/test/any_of/param/config.yaml
@@ -0,0 +1,5 @@
+package: param
+generate:
+  models: true
+  client: true
+output: param.gen.go
diff --git a/internal/test/any_of/param/doc.go b/internal/test/any_of/param/doc.go
new file mode 100644
index 0000000..63ff223
--- /dev/null
+++ b/internal/test/any_of/param/doc.go
@@ -0,0 +1,3 @@
+package param
+
+//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/any_of/param/param.gen.go b/internal/test/any_of/param/param.gen.go
new file mode 100644
index 0000000..7de9459
--- /dev/null
+++ b/internal/test/any_of/param/param.gen.go
@@ -0,0 +1,419 @@
+// Package param provides primitives to interact with the openapi HTTP API.
+//
+// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
+package param
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+
+	"github.com/deepmap/oapi-codegen/pkg/runtime"
+)
+
+// Test defines model for test.
+type Test struct {
+	union json.RawMessage
+}
+
+// Test0 defines model for .
+type Test0 struct {
+	Item1 string `json:"item1"`
+	Item2 string `json:"item2"`
+}
+
+// Test1 defines model for .
+type Test1 struct {
+	Item2 *string `json:"item2,omitempty"`
+	Item3 *string `json:"item3,omitempty"`
+}
+
+// Test2 defines model for test2.
+type Test2 struct {
+	union json.RawMessage
+}
+
+// Test20 defines model for .
+type Test20 = int
+
+// Test21 defines model for .
+type Test21 = string
+
+// GetTestParams defines parameters for GetTest.
+type GetTestParams struct {
+	Test  *Test    `form:"test,omitempty" json:"test,omitempty"`
+	Test2 *[]Test2 `form:"test2,omitempty" json:"test2,omitempty"`
+}
+
+// AsTest0 returns the union data inside the Test as a Test0
+func (t Test) AsTest0() (Test0, error) {
+	var body Test0
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromTest0 overwrites any union data inside the Test as the provided Test0
+func (t *Test) FromTest0(v Test0) error {
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeTest0 performs a merge with any union data inside the Test, using the provided Test0
+func (t *Test) MergeTest0(v Test0) error {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+// AsTest1 returns the union data inside the Test as a Test1
+func (t Test) AsTest1() (Test1, error) {
+	var body Test1
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromTest1 overwrites any union data inside the Test as the provided Test1
+func (t *Test) FromTest1(v Test1) error {
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeTest1 performs a merge with any union data inside the Test, using the provided Test1
+func (t *Test) MergeTest1(v Test1) error {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+func (t Test) MarshalJSON() ([]byte, error) {
+	b, err := t.union.MarshalJSON()
+	return b, err
+}
+
+func (t *Test) UnmarshalJSON(b []byte) error {
+	err := t.union.UnmarshalJSON(b)
+	return err
+}
+
+// AsTest20 returns the union data inside the Test2 as a Test20
+func (t Test2) AsTest20() (Test20, error) {
+	var body Test20
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromTest20 overwrites any union data inside the Test2 as the provided Test20
+func (t *Test2) FromTest20(v Test20) error {
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeTest20 performs a merge with any union data inside the Test2, using the provided Test20
+func (t *Test2) MergeTest20(v Test20) error {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+// AsTest21 returns the union data inside the Test2 as a Test21
+func (t Test2) AsTest21() (Test21, error) {
+	var body Test21
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromTest21 overwrites any union data inside the Test2 as the provided Test21
+func (t *Test2) FromTest21(v Test21) error {
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeTest21 performs a merge with any union data inside the Test2, using the provided Test21
+func (t *Test2) MergeTest21(v Test21) error {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+func (t Test2) MarshalJSON() ([]byte, error) {
+	b, err := t.union.MarshalJSON()
+	return b, err
+}
+
+func (t *Test2) UnmarshalJSON(b []byte) error {
+	err := t.union.UnmarshalJSON(b)
+	return err
+}
+
+// RequestEditorFn  is the function signature for the RequestEditor callback function
+type RequestEditorFn func(ctx context.Context, req *http.Request) error
+
+// Doer performs HTTP requests.
+//
+// The standard http.Client implements this interface.
+type HttpRequestDoer interface {
+	Do(req *http.Request) (*http.Response, error)
+}
+
+// Client which conforms to the OpenAPI3 specification for this service.
+type Client struct {
+	// The endpoint of the server conforming to this interface, with scheme,
+	// https://api.deepmap.com for example. This can contain a path relative
+	// to the server, such as https://api.deepmap.com/dev-test, and all the
+	// paths in the swagger spec will be appended to the server.
+	Server string
+
+	// Doer for performing requests, typically a *http.Client with any
+	// customized settings, such as certificate chains.
+	Client HttpRequestDoer
+
+	// A list of callbacks for modifying requests which are generated before sending over
+	// the network.
+	RequestEditors []RequestEditorFn
+}
+
+// ClientOption allows setting custom parameters during construction
+type ClientOption func(*Client) error
+
+// Creates a new Client, with reasonable defaults
+func NewClient(server string, opts ...ClientOption) (*Client, error) {
+	// create a client with sane default values
+	client := Client{
+		Server: server,
+	}
+	// mutate client and add all optional params
+	for _, o := range opts {
+		if err := o(&client); err != nil {
+			return nil, err
+		}
+	}
+	// ensure the server URL always has a trailing slash
+	if !strings.HasSuffix(client.Server, "/") {
+		client.Server += "/"
+	}
+	// create httpClient, if not already present
+	if client.Client == nil {
+		client.Client = &http.Client{}
+	}
+	return &client, nil
+}
+
+// WithHTTPClient allows overriding the default Doer, which is
+// automatically created using http.Client. This is useful for tests.
+func WithHTTPClient(doer HttpRequestDoer) ClientOption {
+	return func(c *Client) error {
+		c.Client = doer
+		return nil
+	}
+}
+
+// WithRequestEditorFn allows setting up a callback function, which will be
+// called right before sending the request. This can be used to mutate the request.
+func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
+	return func(c *Client) error {
+		c.RequestEditors = append(c.RequestEditors, fn)
+		return nil
+	}
+}
+
+// The interface specification for the client above.
+type ClientInterface interface {
+	// GetTest request
+	GetTest(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*http.Response, error)
+}
+
+func (c *Client) GetTest(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewGetTestRequest(c.Server, params)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	if err := c.applyEditors(ctx, req, reqEditors); err != nil {
+		return nil, err
+	}
+	return c.Client.Do(req)
+}
+
+// NewGetTestRequest generates requests for GetTest
+func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, error) {
+	var err error
+
+	serverURL, err := url.Parse(server)
+	if err != nil {
+		return nil, err
+	}
+
+	operationPath := fmt.Sprintf("/test")
+	if operationPath[0] == '/' {
+		operationPath = "." + operationPath
+	}
+
+	queryURL, err := serverURL.Parse(operationPath)
+	if err != nil {
+		return nil, err
+	}
+
+	queryValues := queryURL.Query()
+
+	if params.Test != nil {
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "test", runtime.ParamLocationQuery, *params.Test); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+	}
+
+	if params.Test2 != nil {
+
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "test2", runtime.ParamLocationQuery, *params.Test2); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
+			}
+		}
+
+	}
+
+	queryURL.RawQuery = queryValues.Encode()
+
+	req, err := http.NewRequest("GET", queryURL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return req, nil
+}
+
+func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
+	for _, r := range c.RequestEditors {
+		if err := r(ctx, req); err != nil {
+			return err
+		}
+	}
+	for _, r := range additionalEditors {
+		if err := r(ctx, req); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// ClientWithResponses builds on ClientInterface to offer response payloads
+type ClientWithResponses struct {
+	ClientInterface
+}
+
+// NewClientWithResponses creates a new ClientWithResponses, which wraps
+// Client with return type handling
+func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) {
+	client, err := NewClient(server, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &ClientWithResponses{client}, nil
+}
+
+// WithBaseURL overrides the baseURL.
+func WithBaseURL(baseURL string) ClientOption {
+	return func(c *Client) error {
+		newBaseURL, err := url.Parse(baseURL)
+		if err != nil {
+			return err
+		}
+		c.Server = newBaseURL.String()
+		return nil
+	}
+}
+
+// ClientWithResponsesInterface is the interface specification for the client with responses above.
+type ClientWithResponsesInterface interface {
+	// GetTest request
+	GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error)
+}
+
+type GetTestResponse struct {
+	Body         []byte
+	HTTPResponse *http.Response
+}
+
+// Status returns HTTPResponse.Status
+func (r GetTestResponse) Status() string {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.Status
+	}
+	return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r GetTestResponse) StatusCode() int {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.StatusCode
+	}
+	return 0
+}
+
+// GetTestWithResponse request returning *GetTestResponse
+func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) {
+	rsp, err := c.GetTest(ctx, params, reqEditors...)
+	if err != nil {
+		return nil, err
+	}
+	return ParseGetTestResponse(rsp)
+}
+
+// ParseGetTestResponse parses an HTTP response from a GetTestWithResponse call
+func ParseGetTestResponse(rsp *http.Response) (*GetTestResponse, error) {
+	bodyBytes, err := io.ReadAll(rsp.Body)
+	defer func() { _ = rsp.Body.Close() }()
+	if err != nil {
+		return nil, err
+	}
+
+	response := &GetTestResponse{
+		Body:         bodyBytes,
+		HTTPResponse: rsp,
+	}
+
+	return response, nil
+}
diff --git a/internal/test/any_of/param/param_test.go b/internal/test/any_of/param/param_test.go
new file mode 100644
index 0000000..748ebc5
--- /dev/null
+++ b/internal/test/any_of/param/param_test.go
@@ -0,0 +1,38 @@
+package param_test
+
+import (
+	"testing"
+
+	"github.com/deepmap/oapi-codegen/internal/test/any_of/param"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestAnyOfParameter(t *testing.T) {
+	var p param.GetTestParams
+
+	p.Test = new(param.Test)
+	err := p.Test.FromTest0(param.Test0{
+		Item1: "foo",
+		Item2: "bar",
+	})
+	require.NoError(t, err)
+
+	hp, err := param.NewGetTestRequest("", &p)
+	assert.NoError(t, err)
+	assert.Equal(t, "/test?item1=foo&item2=bar", hp.URL.String())
+}
+
+func TestArrayOfAnyOfParameter(t *testing.T) {
+	var p param.GetTestParams
+
+	p.Test2 = &[]param.Test2{
+		{},
+	}
+	err := (*p.Test2)[0].FromTest20(100)
+	require.NoError(t, err)
+
+	hp, err := param.NewGetTestRequest("", &p)
+	assert.NoError(t, err)
+	assert.Equal(t, "/test?test2=100", hp.URL.String())
+}
diff --git a/internal/test/any_of/param/spec.yaml b/internal/test/any_of/param/spec.yaml
new file mode 100644
index 0000000..090c97c
--- /dev/null
+++ b/internal/test/any_of/param/spec.yaml
@@ -0,0 +1,42 @@
+openapi: "3.0.0"
+info:
+  version: 1.0.0
+  title: AnyOf parameter
+  description: Checks parameter serialize has AnyOf
+paths:
+  /test:
+    get:
+      parameters:
+      - name: test
+        in: query
+        schema:
+          $ref: '#/components/schemas/test'
+      - name: test2
+        in: query
+        schema:
+          type: array
+          items:
+            $ref: '#/components/schemas/test2'
+components:
+  schemas:
+    test:
+      anyOf:
+        - type: object
+          required:
+            - item1
+            - item2
+          properties:
+            item1:
+              type: string
+            item2:
+              type: string
+        - type: object
+          properties:
+            item2:
+              type: string
+            item3:
+              type: string
+    test2:
+      oneOf:
+        - type: integer
+        - type: string
diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go
index 2553471..d7e23d3 100644
--- a/internal/test/components/components.gen.go
+++ b/internal/test/components/components.gen.go
@@ -243,7 +243,7 @@ type OneOfObject3_Union struct {
 	union json.RawMessage
 }
 
-// OneOfObject4 oneOf plus fixed type - custom marshaling/unmarshaling
+// OneOfObject4 oneOf plus fixed type - custom marshaling/unmarshalling
 type OneOfObject4 struct {
 	FixedProperty *string `json:"fixedProperty,omitempty"`
 	union         json.RawMessage
@@ -435,7 +435,7 @@ func (a *BodyWithAddPropsJSONBody) UnmarshalJSON(b []byte) error {
 			var fieldVal interface{}
 			err := json.Unmarshal(fieldBuf, &fieldVal)
 			if err != nil {
-				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+				return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
 			}
 			a.AdditionalProperties[fieldName] = fieldVal
 		}
@@ -522,7 +522,7 @@ func (a *AdditionalPropertiesObject1) UnmarshalJSON(b []byte) error {
 			var fieldVal int
 			err := json.Unmarshal(fieldBuf, &fieldVal)
 			if err != nil {
-				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+				return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
 			}
 			a.AdditionalProperties[fieldName] = fieldVal
 		}
@@ -600,7 +600,7 @@ func (a *AdditionalPropertiesObject3) UnmarshalJSON(b []byte) error {
 			var fieldVal interface{}
 			err := json.Unmarshal(fieldBuf, &fieldVal)
 			if err != nil {
-				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+				return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
 			}
 			a.AdditionalProperties[fieldName] = fieldVal
 		}
@@ -674,7 +674,7 @@ func (a *AdditionalPropertiesObject4) UnmarshalJSON(b []byte) error {
 			var fieldVal interface{}
 			err := json.Unmarshal(fieldBuf, &fieldVal)
 			if err != nil {
-				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+				return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
 			}
 			a.AdditionalProperties[fieldName] = fieldVal
 		}
@@ -745,7 +745,7 @@ func (a *AdditionalPropertiesObject4_Inner) UnmarshalJSON(b []byte) error {
 			var fieldVal interface{}
 			err := json.Unmarshal(fieldBuf, &fieldVal)
 			if err != nil {
-				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+				return fmt.Errorf("error unmarshalling field %s: %w", fieldName, err)
 			}
 			a.AdditionalProperties[fieldName] = fieldVal
 		}
@@ -987,19 +987,25 @@ func (t OneOfObject10) MarshalJSON() ([]byte, error) {
 		}
 	}
 
-	object["one"], err = json.Marshal(t.One)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling 'one': %w", err)
+	if t.One != nil {
+		object["one"], err = json.Marshal(t.One)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling 'one': %w", err)
+		}
 	}
 
-	object["three"], err = json.Marshal(t.Three)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling 'three': %w", err)
+	if t.Three != nil {
+		object["three"], err = json.Marshal(t.Three)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling 'three': %w", err)
+		}
 	}
 
-	object["two"], err = json.Marshal(t.Two)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling 'two': %w", err)
+	if t.Two != nil {
+		object["two"], err = json.Marshal(t.Two)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling 'two': %w", err)
+		}
 	}
 	b, err = json.Marshal(object)
 	return b, err
@@ -1509,9 +1515,11 @@ func (t OneOfObject4) MarshalJSON() ([]byte, error) {
 		}
 	}
 
-	object["fixedProperty"], err = json.Marshal(t.FixedProperty)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling 'fixedProperty': %w", err)
+	if t.FixedProperty != nil {
+		object["fixedProperty"], err = json.Marshal(t.FixedProperty)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling 'fixedProperty': %w", err)
+		}
 	}
 	b, err = json.Marshal(object)
 	return b, err
@@ -1824,9 +1832,11 @@ func (t OneOfObject8) MarshalJSON() ([]byte, error) {
 		}
 	}
 
-	object["fixed"], err = json.Marshal(t.Fixed)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling 'fixed': %w", err)
+	if t.Fixed != nil {
+		object["fixed"], err = json.Marshal(t.Fixed)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling 'fixed': %w", err)
+		}
 	}
 	b, err = json.Marshal(object)
 	return b, err
@@ -1953,6 +1963,7 @@ func (t OneOfObject9) MarshalJSON() ([]byte, error) {
 	if err != nil {
 		return nil, fmt.Errorf("error marshaling 'type': %w", err)
 	}
+
 	b, err = json.Marshal(object)
 	return b, err
 }
diff --git a/internal/test/components/components.yaml b/internal/test/components/components.yaml
index 4bc4fe7..79e3857 100644
--- a/internal/test/components/components.yaml
+++ b/internal/test/components/components.yaml
@@ -234,7 +234,7 @@ components:
             - $ref: '#/components/schemas/OneOfVariant2'
             - $ref: '#/components/schemas/OneOfVariant3'
     OneOfObject4:
-      description: oneOf plus fixed type - custom marshaling/unmarshaling
+      description: oneOf plus fixed type - custom marshaling/unmarshalling
       type: object
       properties:
         fixedProperty:
diff --git a/internal/test/components/components_test.go b/internal/test/components/components_test.go
index bcb34d7..a6fbbfd 100644
--- a/internal/test/components/components_test.go
+++ b/internal/test/components/components_test.go
@@ -20,7 +20,7 @@ func assertJsonEqual(t *testing.T, j1 []byte, j2 []byte) {
 }
 
 func TestRawJSON(t *testing.T) {
-	// Check raw json unmarshaling
+	// Check raw json unmarshalling
 	const buf = `{"name":"bob","value1":{"present":true}}`
 	var dst ObjectWithJsonField
 	err := json.Unmarshal([]byte(buf), &dst)
@@ -204,7 +204,7 @@ func TestAnyOf(t *testing.T) {
 }
 
 func TestMarshalWhenNoUnionValueSet(t *testing.T) {
-	const expected = `{"one":null,"three":null,"two":null}`
+	const expected = `{}`
 
 	var dst OneOfObject10
 
diff --git a/internal/test/externalref/externalref.gen.go b/internal/test/externalref/externalref.gen.go
index 698bc3f..b9b62d1 100644
--- a/internal/test/externalref/externalref.gen.go
+++ b/internal/test/externalref/externalref.gen.go
@@ -19,16 +19,18 @@ import (
 
 // Container defines model for Container.
 type Container struct {
-	ObjectA *externalRef0.ObjectA `json:"object_a,omitempty"`
-	ObjectB *externalRef1.ObjectB `json:"object_b,omitempty"`
+	ObjectA *externalRef0.ObjectA   `json:"object_a,omitempty"`
+	ObjectB *externalRef1.ObjectB   `json:"object_b,omitempty"`
+	ObjectC *map[string]interface{} `json:"object_c,omitempty"`
 }
 
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"H4sIAAAAAAAC/4zPQcrCMBAF4Lu8/1+GpOAuu9YDeASZhqmNtsmQBEFK7i4pihsXZvUeYb5hNri4Sgwc",
-	"SobdkN3MK+3xGEMhHzi1IikKp+J5/4rjlV05U8v/iSdYaCPkbnTh3mRhpx+0Ln/mg5uXbE77bI+q3sz4",
-	"jRl+YgbU9hR8mGJjii8LwwIKd07Zx9BK2yUcSDwsDrrTHRSEytyuqfUZAAD//0P8tE0FAQAA",
+	"H4sIAAAAAAAC/5yPQU7EMAxF72JYRtOR2GXHcAC4AfJkPNSotaPEIKEqd0dJKa1gQcUqtvzf/z8TBB2j",
+	"Coll8BPk0NOIbXxQMWShVJeYNFIypnbS8ysFe8Y63ya6goebbjXqvly6x6a7h+IW5LwPOW2Q8BfyrSul",
+	"OFgyf5UWHKm+9hEJPGRLLC//qrbGnHbHlB8fwsuFjVVweNrglt7ILegsn1GWqzZXtqHewME7pcwqdane",
+	"kQQjg4e7w/FwBAcRra+NSvkMAAD//3vXjDblAQAA",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/externalref/object_c.json b/internal/test/externalref/object_c.json
new file mode 100644
index 0000000..b85043d
--- /dev/null
+++ b/internal/test/externalref/object_c.json
@@ -0,0 +1,5 @@
+{
+  "type": "object",
+  "properties": {},
+  "additionalProperties": true
+}
diff --git a/internal/test/externalref/packageA/externalref.gen.go b/internal/test/externalref/packageA/externalref.gen.go
index 3b58e3c..01505b1 100644
--- a/internal/test/externalref/packageA/externalref.gen.go
+++ b/internal/test/externalref/packageA/externalref.gen.go
@@ -25,9 +25,9 @@ type ObjectA struct {
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"H4sIAAAAAAAC/0SNQarDMAwF7/L+X5p4711zgR6hKEZJ3MaysN1FCLl7sVOoNhoYHnPAp6hJWGqBO1D8",
-	"ypE63qcn+3prqDkp5xq4C6HI7dddGQ6l5iALToPUF4+pyf/MMxyGwSr5Fy082qLsh53i9md/Ufst2is3",
-	"4mxnEGROcPLeNoOkLKQBDjBQqmu5zPkJAAD//0utOZO+AAAA",
+	"H4sIAAAAAAAC/4yNQa7CMAxE7zL/LyN1nx1cgCOgtHJpUGtbiVmgyndHSUFsWXmsp3mzY5JNhYmtIu6o",
+	"00Jb6vEy3mmyU4taRKlYpg44bdSuPZUQUa1kvsEDpDeuY4P/hWZE/A1f//CWD4f5DHcP+Dy/znhvZZ4F",
+	"kR/rGiBKnDQjAgGabKkH8VcAAAD//0SMp77dAAAA",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/externalref/spec.yaml b/internal/test/externalref/spec.yaml
index 3f42c7d..ba0ae65 100644
--- a/internal/test/externalref/spec.yaml
+++ b/internal/test/externalref/spec.yaml
@@ -9,3 +9,5 @@ components:
           $ref: ./packageA/spec.yaml#/components/schemas/ObjectA
         object_b:
           $ref: ./packageB/spec.yaml#/components/schemas/ObjectB
+        object_c:
+          $ref: ./object_c.json
diff --git a/internal/test/issues/issue-head-digit-of-operation-id/config.yaml b/internal/test/issues/issue-head-digit-of-operation-id/config.yaml
new file mode 100644
index 0000000..5823c79
--- /dev/null
+++ b/internal/test/issues/issue-head-digit-of-operation-id/config.yaml
@@ -0,0 +1,7 @@
+---
+package: head_digit_of_operation_id
+generate:
+  strict-server: true
+output: issue.gen.go
+output-options:
+  skip-prune: true
diff --git a/internal/test/issues/issue-head-digit-of-operation-id/doc.go b/internal/test/issues/issue-head-digit-of-operation-id/doc.go
new file mode 100644
index 0000000..6faae82
--- /dev/null
+++ b/internal/test/issues/issue-head-digit-of-operation-id/doc.go
@@ -0,0 +1,3 @@
+package head_digit_of_operation_id
+
+//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-head-digit-of-operation-id/issue.gen.go b/internal/test/issues/issue-head-digit-of-operation-id/issue.gen.go
new file mode 100644
index 0000000..1760746
--- /dev/null
+++ b/internal/test/issues/issue-head-digit-of-operation-id/issue.gen.go
@@ -0,0 +1,23 @@
+// Package head_digit_of_operation_id provides primitives to interact with the openapi HTTP API.
+//
+// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
+package head_digit_of_operation_id
+
+import (
+	"context"
+	"net/http"
+)
+
+type N3GPPFooRequestObject struct {
+}
+
+type N3GPPFooResponseObject interface {
+	VisitN3GPPFooResponse(w http.ResponseWriter) error
+}
+
+// StrictServerInterface represents all server handlers.
+type StrictServerInterface interface {
+
+	// (GET /3gpp/foo)
+	N3GPPFoo(ctx context.Context, request N3GPPFooRequestObject) (N3GPPFooResponseObject, error)
+}
diff --git a/internal/test/issues/issue-head-digit-of-operation-id/spec.yaml b/internal/test/issues/issue-head-digit-of-operation-id/spec.yaml
new file mode 100644
index 0000000..59efb77
--- /dev/null
+++ b/internal/test/issues/issue-head-digit-of-operation-id/spec.yaml
@@ -0,0 +1,7 @@
+openapi: 3.0.2
+info:
+  version: "0.0.1"
+paths:
+  /3gpp/foo:
+    get:
+      operationId: 3GPPFoo
diff --git a/internal/test/parameters/parameters.gen.go b/internal/test/parameters/parameters.gen.go
index 9d0fc0e..45d11b4 100644
--- a/internal/test/parameters/parameters.gen.go
+++ b/internal/test/parameters/parameters.gen.go
@@ -2746,7 +2746,7 @@ func (w *ServerInterfaceWrapper) GetContentObject(ctx echo.Context) error {
 
 	err = json.Unmarshal([]byte(ctx.Param("param")), &param)
 	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'param' as JSON")
+		return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter 'param' as JSON")
 	}
 
 	// Invoke the callback with all the unmarshalled arguments
@@ -2837,7 +2837,7 @@ func (w *ServerInterfaceWrapper) GetCookie(ctx echo.Context) error {
 		}
 		err = json.Unmarshal([]byte(decoded), &value)
 		if err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON")
+			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter 'co' as JSON")
 		}
 		params.Co = &value
 
@@ -2985,7 +2985,7 @@ func (w *ServerInterfaceWrapper) GetHeader(ctx echo.Context) error {
 
 		err = json.Unmarshal([]byte(valueList[0]), &XComplexObject)
 		if err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'X-Complex-Object' as JSON")
+			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter 'X-Complex-Object' as JSON")
 		}
 
 		params.XComplexObject = &XComplexObject
@@ -3232,7 +3232,7 @@ func (w *ServerInterfaceWrapper) GetQueryForm(ctx echo.Context) error {
 		var value ComplexObject
 		err = json.Unmarshal([]byte(paramValue), &value)
 		if err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON")
+			return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshalling parameter 'co' as JSON")
 		}
 		params.Co = &value
 
diff --git a/internal/test/server/doc.go b/internal/test/server/doc.go
index 91e93b5..1f7a617 100644
--- a/internal/test/server/doc.go
+++ b/internal/test/server/doc.go
@@ -1,4 +1,8 @@
 package server
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml ../test-schema.yaml
-//go:generate go run github.com/matryer/moq -out server_moq.gen.go . ServerInterface
+
+// This is commented out because the server_mog.gen.go keeps changing for no good reason, and
+// so, precommit checks fail. We need to regenerate this file occasionally manually.
+// TODO(mromaszewicz) - figure out why this file drifts and fix it.
+// go:generate go run github.com/matryer/moq -out server_moq.gen.go . ServerInterface
diff --git a/internal/test/server/server.gen.go b/internal/test/server/server.gen.go
index d676d16..d43de70 100644
--- a/internal/test/server/server.gen.go
+++ b/internal/test/server/server.gen.go
@@ -458,16 +458,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
 	return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
 	ParamName string
 	Err       error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-	return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
 	return e.Err
 }
 
diff --git a/internal/test/server/server_moq.gen.go b/internal/test/server/server_moq.gen.go
index aa22e65..80bc73a 100644
--- a/internal/test/server/server_moq.gen.go
+++ b/internal/test/server/server_moq.gen.go
@@ -14,46 +14,46 @@ var _ ServerInterface = &ServerInterfaceMock{}
 
 // ServerInterfaceMock is a mock implementation of ServerInterface.
 //
-// 	func TestSomethingThatUsesServerInterface(t *testing.T) {
+//	func TestSomethingThatUsesServerInterface(t *testing.T) {
 //
-// 		// make and configure a mocked ServerInterface
-// 		mockedServerInterface := &ServerInterfaceMock{
-// 			CreateResourceFunc: func(w http.ResponseWriter, r *http.Request, argument string)  {
-// 				panic("mock out the CreateResource method")
-// 			},
-// 			CreateResource2Func: func(w http.ResponseWriter, r *http.Request, inlineArgument int, params CreateResource2Params)  {
-// 				panic("mock out the CreateResource2 method")
-// 			},
-// 			GetEveryTypeOptionalFunc: func(w http.ResponseWriter, r *http.Request)  {
-// 				panic("mock out the GetEveryTypeOptional method")
-// 			},
-// 			GetReservedKeywordFunc: func(w http.ResponseWriter, r *http.Request)  {
-// 				panic("mock out the GetReservedKeyword method")
-// 			},
-// 			GetResponseWithReferenceFunc: func(w http.ResponseWriter, r *http.Request)  {
-// 				panic("mock out the GetResponseWithReference method")
-// 			},
-// 			GetSimpleFunc: func(w http.ResponseWriter, r *http.Request)  {
-// 				panic("mock out the GetSimple method")
-// 			},
-// 			GetWithArgsFunc: func(w http.ResponseWriter, r *http.Request, params GetWithArgsParams)  {
-// 				panic("mock out the GetWithArgs method")
-// 			},
-// 			GetWithContentTypeFunc: func(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType)  {
-// 				panic("mock out the GetWithContentType method")
-// 			},
-// 			GetWithReferencesFunc: func(w http.ResponseWriter, r *http.Request, globalArgument int64, argument string)  {
-// 				panic("mock out the GetWithReferences method")
-// 			},
-// 			UpdateResource3Func: func(w http.ResponseWriter, r *http.Request, pFallthrough int)  {
-// 				panic("mock out the UpdateResource3 method")
-// 			},
-// 		}
+//		// make and configure a mocked ServerInterface
+//		mockedServerInterface := &ServerInterfaceMock{
+//			CreateResourceFunc: func(w http.ResponseWriter, r *http.Request, argument string)  {
+//				panic("mock out the CreateResource method")
+//			},
+//			CreateResource2Func: func(w http.ResponseWriter, r *http.Request, inlineArgument int, params CreateResource2Params)  {
+//				panic("mock out the CreateResource2 method")
+//			},
+//			GetEveryTypeOptionalFunc: func(w http.ResponseWriter, r *http.Request)  {
+//				panic("mock out the GetEveryTypeOptional method")
+//			},
+//			GetReservedKeywordFunc: func(w http.ResponseWriter, r *http.Request)  {
+//				panic("mock out the GetReservedKeyword method")
+//			},
+//			GetResponseWithReferenceFunc: func(w http.ResponseWriter, r *http.Request)  {
+//				panic("mock out the GetResponseWithReference method")
+//			},
+//			GetSimpleFunc: func(w http.ResponseWriter, r *http.Request)  {
+//				panic("mock out the GetSimple method")
+//			},
+//			GetWithArgsFunc: func(w http.ResponseWriter, r *http.Request, params GetWithArgsParams)  {
+//				panic("mock out the GetWithArgs method")
+//			},
+//			GetWithContentTypeFunc: func(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType)  {
+//				panic("mock out the GetWithContentType method")
+//			},
+//			GetWithReferencesFunc: func(w http.ResponseWriter, r *http.Request, globalArgument int64, argument string)  {
+//				panic("mock out the GetWithReferences method")
+//			},
+//			UpdateResource3Func: func(w http.ResponseWriter, r *http.Request, pFallthrough int)  {
+//				panic("mock out the UpdateResource3 method")
+//			},
+//		}
 //
-// 		// use mockedServerInterface in code that requires ServerInterface
-// 		// and then make assertions.
+//		// use mockedServerInterface in code that requires ServerInterface
+//		// and then make assertions.
 //
-// 	}
+//	}
 type ServerInterfaceMock struct {
 	// CreateResourceFunc mocks the CreateResource method.
 	CreateResourceFunc func(w http.ResponseWriter, r *http.Request, argument string)
@@ -208,7 +208,8 @@ func (mock *ServerInterfaceMock) CreateResource(w http.ResponseWriter, r *http.R
 
 // CreateResourceCalls gets all the calls that were made to CreateResource.
 // Check the length with:
-//     len(mockedServerInterface.CreateResourceCalls())
+//
+//	len(mockedServerInterface.CreateResourceCalls())
 func (mock *ServerInterfaceMock) CreateResourceCalls() []struct {
 	W        http.ResponseWriter
 	R        *http.Request
@@ -249,7 +250,8 @@ func (mock *ServerInterfaceMock) CreateResource2(w http.ResponseWriter, r *http.
 
 // CreateResource2Calls gets all the calls that were made to CreateResource2.
 // Check the length with:
-//     len(mockedServerInterface.CreateResource2Calls())
+//
+//	len(mockedServerInterface.CreateResource2Calls())
 func (mock *ServerInterfaceMock) CreateResource2Calls() []struct {
 	W              http.ResponseWriter
 	R              *http.Request
@@ -288,7 +290,8 @@ func (mock *ServerInterfaceMock) GetEveryTypeOptional(w http.ResponseWriter, r *
 
 // GetEveryTypeOptionalCalls gets all the calls that were made to GetEveryTypeOptional.
 // Check the length with:
-//     len(mockedServerInterface.GetEveryTypeOptionalCalls())
+//
+//	len(mockedServerInterface.GetEveryTypeOptionalCalls())
 func (mock *ServerInterfaceMock) GetEveryTypeOptionalCalls() []struct {
 	W http.ResponseWriter
 	R *http.Request
@@ -323,7 +326,8 @@ func (mock *ServerInterfaceMock) GetReservedKeyword(w http.ResponseWriter, r *ht
 
 // GetReservedKeywordCalls gets all the calls that were made to GetReservedKeyword.
 // Check the length with:
-//     len(mockedServerInterface.GetReservedKeywordCalls())
+//
+//	len(mockedServerInterface.GetReservedKeywordCalls())
 func (mock *ServerInterfaceMock) GetReservedKeywordCalls() []struct {
 	W http.ResponseWriter
 	R *http.Request
@@ -358,7 +362,8 @@ func (mock *ServerInterfaceMock) GetResponseWithReference(w http.ResponseWriter,
 
 // GetResponseWithReferenceCalls gets all the calls that were made to GetResponseWithReference.
 // Check the length with:
-//     len(mockedServerInterface.GetResponseWithReferenceCalls())
+//
+//	len(mockedServerInterface.GetResponseWithReferenceCalls())
 func (mock *ServerInterfaceMock) GetResponseWithReferenceCalls() []struct {
 	W http.ResponseWriter
 	R *http.Request
@@ -393,7 +398,8 @@ func (mock *ServerInterfaceMock) GetSimple(w http.ResponseWriter, r *http.Reques
 
 // GetSimpleCalls gets all the calls that were made to GetSimple.
 // Check the length with:
-//     len(mockedServerInterface.GetSimpleCalls())
+//
+//	len(mockedServerInterface.GetSimpleCalls())
 func (mock *ServerInterfaceMock) GetSimpleCalls() []struct {
 	W http.ResponseWriter
 	R *http.Request
@@ -430,7 +436,8 @@ func (mock *ServerInterfaceMock) GetWithArgs(w http.ResponseWriter, r *http.Requ
 
 // GetWithArgsCalls gets all the calls that were made to GetWithArgs.
 // Check the length with:
-//     len(mockedServerInterface.GetWithArgsCalls())
+//
+//	len(mockedServerInterface.GetWithArgsCalls())
 func (mock *ServerInterfaceMock) GetWithArgsCalls() []struct {
 	W      http.ResponseWriter
 	R      *http.Request
@@ -469,7 +476,8 @@ func (mock *ServerInterfaceMock) GetWithContentType(w http.ResponseWriter, r *ht
 
 // GetWithContentTypeCalls gets all the calls that were made to GetWithContentType.
 // Check the length with:
-//     len(mockedServerInterface.GetWithContentTypeCalls())
+//
+//	len(mockedServerInterface.GetWithContentTypeCalls())
 func (mock *ServerInterfaceMock) GetWithContentTypeCalls() []struct {
 	W           http.ResponseWriter
 	R           *http.Request
@@ -510,7 +518,8 @@ func (mock *ServerInterfaceMock) GetWithReferences(w http.ResponseWriter, r *htt
 
 // GetWithReferencesCalls gets all the calls that were made to GetWithReferences.
 // Check the length with:
-//     len(mockedServerInterface.GetWithReferencesCalls())
+//
+//	len(mockedServerInterface.GetWithReferencesCalls())
 func (mock *ServerInterfaceMock) GetWithReferencesCalls() []struct {
 	W              http.ResponseWriter
 	R              *http.Request
@@ -551,7 +560,8 @@ func (mock *ServerInterfaceMock) UpdateResource3(w http.ResponseWriter, r *http.
 
 // UpdateResource3Calls gets all the calls that were made to UpdateResource3.
 // Check the length with:
-//     len(mockedServerInterface.UpdateResource3Calls())
+//
+//	len(mockedServerInterface.UpdateResource3Calls())
 func (mock *ServerInterfaceMock) UpdateResource3Calls() []struct {
 	W            http.ResponseWriter
 	R            *http.Request
diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go
index 06dbc6c..1004665 100644
--- a/internal/test/strict-server/chi/server.gen.go
+++ b/internal/test/strict-server/chi/server.gen.go
@@ -259,16 +259,16 @@ func (e *UnescapedCookieParamError) Unwrap() error {
 	return e.Err
 }
 
-type UnmarshalingParamError struct {
+type UnmarshallingParamError struct {
 	ParamName string
 	Err       error
 }
 
-func (e *UnmarshalingParamError) Error() string {
-	return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
+func (e *UnmarshallingParamError) Error() string {
+	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
 }
 
-func (e *UnmarshalingParamError) Unwrap() error {
+func (e *UnmarshallingParamError) Unwrap() error {
 	return e.Err
 }
 
diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go
index 5192a0d..837cb70 100644
--- a/internal/test/strict-server/gin/server.gen.go
+++ b/internal/test/strict-server/gin/server.gen.go
@@ -57,6 +57,7 @@ type ServerInterface interface {
 type ServerInterfaceWrapper struct {
 	Handler            ServerInterface
 	HandlerMiddlewares []MiddlewareFunc
+	ErrorHandler       func(*gin.Context, error, int)
 }
 
 type MiddlewareFunc func(c *gin.Context)
@@ -156,20 +157,20 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *gin.Context) {
 		var Header1 string
 		n := len(valueList)
 		if n != 1 {
-			c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Expected one value for header1, got %d", n)})
+			siw.ErrorHandler(c, fmt.Errorf("Expected one value for header1, got %d", n), http.StatusBadRequest)
 			return
 		}
 
 		err = runtime.BindStyledParameterWithLocation("simple", false, "header1", runtime.ParamLocationHeader, valueList[0], &Header1)
 		if err != nil {
-			c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter header1: %s", err)})
+			siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter header1: %s", err), http.StatusBadRequest)
 			return
 		}
 
 		params.Header1 = Header1
 
 	} else {
-		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Header parameter header1 is required, but not found: %s", err)})
+		siw.ErrorHandler(c, fmt.Errorf("Header parameter header1 is required, but not found: %s", err), http.StatusBadRequest)
 		return
 	}
 
@@ -178,13 +179,13 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *gin.Context) {
 		var Header2 int
 		n := len(valueList)
 		if n != 1 {
-			c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Expected one value for header2, got %d", n)})
+			siw.ErrorHandler(c, fmt.Errorf("Expected one value for header2, got %d", n), http.StatusBadRequest)
 			return
 		}
 
 		err = runtime.BindStyledParameterWithLocation("simple", false, "header2", runtime.ParamLocationHeader, valueList[0], &Header2)
 		if err != nil {
-			c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter header2: %s", err)})
+			siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter header2: %s", err), http.StatusBadRequest)
 			return
 		}
 
@@ -201,8 +202,9 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *gin.Context) {
 
 // GinServerOptions provides options for the Gin server.
 type GinServerOptions struct {
-	BaseURL     string
-	Middlewares []MiddlewareFunc
+	BaseURL      string
+	Middlewares  []MiddlewareFunc
+	ErrorHandler func(*gin.Context, error, int)
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
@@ -212,9 +214,19 @@ func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
 func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
+
+	errorHandler := options.ErrorHandler
+
+	if errorHandler == nil {
+		errorHandler = func(c *gin.Context, err error, statusCode int) {
+			c.JSON(statusCode, gin.H{"msg": err.Error()})
+		}
+	}
+
 	wrapper := ServerInterfaceWrapper{
 		Handler:            si,
 		HandlerMiddlewares: options.Middlewares,
+		ErrorHandler:       errorHandler,
 	}
 
 	router.POST(options.BaseURL+"/json", wrapper.JSONExample)
diff --git a/pkg/chi-middleware/oapi_validate_test.go b/pkg/chi-middleware/oapi_validate_test.go
index 8d92ba7..d10df5c 100644
--- a/pkg/chi-middleware/oapi_validate_test.go
+++ b/pkg/chi-middleware/oapi_validate_test.go
@@ -321,7 +321,7 @@ func TestOapiRequestValidatorWithOptions(t *testing.T) {
 	{
 		rec := doGet(t, r, "http://deepmap.ai/protected_resource_401")
 		assert.Equal(t, http.StatusUnauthorized, rec.Code)
-		assert.Equal(t, "test: Security requirements failed\n", rec.Body.String())
+		assert.Equal(t, "test: security requirements failed: unauthorized\n", rec.Body.String())
 		assert.False(t, called, "Handler should not have been called")
 		called = false
 	}
diff --git a/pkg/gin-middleware/oapi_validate_test.go b/pkg/gin-middleware/oapi_validate_test.go
index 3ad2f1c..30ad57f 100644
--- a/pkg/gin-middleware/oapi_validate_test.go
+++ b/pkg/gin-middleware/oapi_validate_test.go
@@ -198,7 +198,7 @@ func TestOapiRequestValidator(t *testing.T) {
 	{
 		rec := doGet(t, g, "http://deepmap.ai/protected_resource_401")
 		assert.Equal(t, http.StatusBadRequest, rec.Code)
-		assert.Equal(t, "test: error in openapi3filter.SecurityRequirementsError: Security requirements failed", rec.Body.String())
+		assert.Equal(t, "test: error in openapi3filter.SecurityRequirementsError: security requirements failed: unauthorized", rec.Body.String())
 		assert.False(t, called, "Handler should not have been called")
 		called = false
 	}
diff --git a/pkg/testutil/request_helpers.go b/pkg/testutil/request_helpers.go
index e0f8c08..e54f535 100644
--- a/pkg/testutil/request_helpers.go
+++ b/pkg/testutil/request_helpers.go
@@ -14,7 +14,7 @@
 package testutil
 
 // This is a set of fluent request builders for tests, which help us to
-// simplify constructing and unmarshaling test objects. For example, to post
+// simplify constructing and unmarshalling test objects. For example, to post
 // a body and return a response, you would do something like:
 //
 //   var body RequestBody