Repository: deepmap/oapi-codegen
Pull request #232 (2020-09-21 21:36:25)

Type aliasing
Some types are unnecessary wrapped, for example 
```go
type AddPetJSONRequestBody Pet
```
which lengthens the code needed to create and handle such types.

I added an option, called `-alias-types`, that changes all types satisfying:
```go
type A struct { /* ... */ } // unchanged
type B string // native type wrappers are unchanged, they are useful for e.g. enums
type C = A  // Direct wrappers of another defined type is aliased
type D = []A // Array of referenced types are aliased
type E []int // Array of non-referenced types are not aliased
```

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/deepmap/oapi-codegen/232)
<!-- Reviewable:end -->



Patch:
diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go
index 8a02e89..f1c509d 100644
--- a/cmd/oapi-codegen/oapi-codegen.go
+++ b/cmd/oapi-codegen/oapi-codegen.go
@@ -43,6 +43,7 @@ var (
 	flagImportMapping  string
 	flagExcludeSchemas string
 	flagConfigFile     string
+	flagAliasTypes     bool
 )
 
 type configuration struct {
@@ -68,6 +69,7 @@ func main() {
 	flag.StringVar(&flagImportMapping, "import-mapping", "", "A dict from the external reference to golang package path")
 	flag.StringVar(&flagExcludeSchemas, "exclude-schemas", "", "A comma separated list of schemas which must be excluded from generation")
 	flag.StringVar(&flagConfigFile, "config", "", "a YAML config file that controls oapi-codegen behavior")
+	flag.BoolVar(&flagAliasTypes, "alias-types", false, "Alias type declarations of possible")
 	flag.Parse()
 
 	if flag.NArg() < 1 {
@@ -87,7 +89,9 @@ func main() {
 		cfg.PackageName = codegen.ToCamelCase(nameParts[0])
 	}
 
-	opts := codegen.Options{}
+	opts := codegen.Options{
+		AliasTypes: flagAliasTypes,
+	}
 	for _, g := range cfg.GenerateTargets {
 		switch g {
 		case "client":
diff --git a/examples/petstore-expanded/chi/api/petstore.gen.go b/examples/petstore-expanded/chi/api/petstore.gen.go
index 7f3ced8..a95657f 100644
--- a/examples/petstore-expanded/chi/api/petstore.gen.go
+++ b/examples/petstore-expanded/chi/api/petstore.gen.go
@@ -59,7 +59,7 @@ type FindPetsParams struct {
 // AddPetJSONBody defines parameters for AddPet.
 type AddPetJSONBody NewPet
 
-// AddPetRequestBody defines body for AddPet for application/json ContentType.
+// AddPetJSONRequestBody defines body for AddPet for application/json ContentType.
 type AddPetJSONRequestBody AddPetJSONBody
 
 // ServerInterface represents all server handlers.
diff --git a/examples/petstore-expanded/echo/api/petstore-types.gen.go b/examples/petstore-expanded/echo/api/petstore-types.gen.go
index b9335b0..c690051 100644
--- a/examples/petstore-expanded/echo/api/petstore-types.gen.go
+++ b/examples/petstore-expanded/echo/api/petstore-types.gen.go
@@ -46,5 +46,5 @@ type FindPetsParams struct {
 // AddPetJSONBody defines parameters for AddPet.
 type AddPetJSONBody NewPet
 
-// AddPetRequestBody defines body for AddPet for application/json ContentType.
+// AddPetJSONRequestBody defines body for AddPet for application/json ContentType.
 type AddPetJSONRequestBody AddPetJSONBody
diff --git a/examples/petstore-expanded/petstore-client.gen.go b/examples/petstore-expanded/petstore-client.gen.go
index 3822944..1682194 100644
--- a/examples/petstore-expanded/petstore-client.gen.go
+++ b/examples/petstore-expanded/petstore-client.gen.go
@@ -60,7 +60,7 @@ type FindPetsParams struct {
 // AddPetJSONBody defines parameters for AddPet.
 type AddPetJSONBody NewPet
 
-// AddPetRequestBody defines body for AddPet for application/json ContentType.
+// AddPetJSONRequestBody defines body for AddPet for application/json ContentType.
 type AddPetJSONRequestBody AddPetJSONBody
 
 // RequestEditorFn  is the function signature for the RequestEditor callback function
@@ -325,6 +325,7 @@ func NewAddPetRequestWithBody(server string, contentType string, body io.Reader)
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go
index aeb376c..73d11d6 100644
--- a/pkg/codegen/codegen.go
+++ b/pkg/codegen/codegen.go
@@ -38,6 +38,7 @@ type Options struct {
 	EmbedSpec          bool              // Whether to embed the swagger spec in the generated code
 	SkipFmt            bool              // Whether to skip go imports on the generated code
 	SkipPrune          bool              // Whether to skip pruning unused components on the generated code
+	AliasTypes         bool              // Whether to alias types if possible
 	IncludeTags        []string          // Only include operations that have one of these tags. Ignored when empty.
 	ExcludeTags        []string          // Exclude operations that have one of these tags. Ignored when empty.
 	UserTemplates      map[string]string // Override built-in templates from user-provided files
@@ -110,6 +111,7 @@ func Generate(swagger *openapi3.Swagger, packageName string, opts Options) (stri
 	}
 
 	// This creates the golang templates text package
+	TemplateFunctions["opts"] = func() Options { return opts }
 	t := template.New("oapi-codegen").Funcs(TemplateFunctions)
 	// This parses all of our own template files into the template object
 	// above
diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go
index 916643d..7eb137f 100644
--- a/pkg/codegen/operations.go
+++ b/pkg/codegen/operations.go
@@ -333,8 +333,11 @@ type RequestBodyDefinition struct {
 }
 
 // Returns the Go type definition for a request body
-func (r RequestBodyDefinition) TypeDef() string {
-	return r.Schema.TypeDecl()
+func (r RequestBodyDefinition) TypeDef(opID string) *TypeDefinition {
+	return &TypeDefinition{
+		TypeName: fmt.Sprintf("%s%sRequestBody", opID, r.NameTag),
+		Schema:   r.Schema,
+	}
 }
 
 // Returns whether the body is a custom inline type, or pre-defined. This is
diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go
index ed13971..de3dcfc 100644
--- a/pkg/codegen/schema.go
+++ b/pkg/codegen/schema.go
@@ -13,6 +13,8 @@ type Schema struct {
 	GoType  string // The Go type needed to represent the schema
 	RefType string // If the type has a type name, this is set
 
+	ArrayType *Schema // The schema of array element
+
 	EnumValues map[string]string // Enum values
 
 	Properties               []Property       // For an object, the fields with names
@@ -81,6 +83,11 @@ type TypeDefinition struct {
 	Schema       Schema
 }
 
+func (t *TypeDefinition) CanAlias() bool {
+	return t.Schema.IsRef() || /* actual reference */
+		(t.Schema.ArrayType != nil && t.Schema.ArrayType.IsRef()) /* array to ref */
+}
+
 func PropertiesEqual(a, b Property) bool {
 	return a.JsonFieldName == b.JsonFieldName && a.Schema.TypeDecl() == b.Schema.TypeDecl() && a.Required == b.Required
 }
@@ -235,6 +242,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
 			if err != nil {
 				return Schema{}, errors.Wrap(err, "error generating type for array")
 			}
+			outSchema.ArrayType = &arrayType
 			outSchema.GoType = "[]" + arrayType.TypeDecl()
 			outSchema.Properties = arrayType.Properties
 		case "integer":
diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl
index 5d264a2..d725248 100644
--- a/pkg/codegen/templates/client.tmpl
+++ b/pkg/codegen/templates/client.tmpl
@@ -217,6 +217,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
         return nil, err
     }
 
+    {{if .HasBody}}req.Header.Add("Content-Type", contentType){{end}}
 {{range $paramIdx, $param := .HeaderParams}}
     {{if not .Required}} if params.{{.GoName}} != nil { {{end}}
     var headerParam{{$paramIdx}} string
@@ -237,7 +238,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
         return nil, err
     }
     {{end}}
-    req.Header.Add("{{.ParamName}}", headerParam{{$paramIdx}})
+    req.Header.Set("{{.ParamName}}", headerParam{{$paramIdx}})
     {{if not .Required}}}{{end}}
 {{end}}
 
@@ -268,7 +269,6 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
     req.AddCookie(cookie{{$paramIdx}})
     {{if not .Required}}}{{end}}
 {{end}}
-    {{if .HasBody}}req.Header.Add("Content-Type", contentType){{end}}
     return req, nil
 }
 
diff --git a/pkg/codegen/templates/param-types.tmpl b/pkg/codegen/templates/param-types.tmpl
index b35cce5..f49ba30 100644
--- a/pkg/codegen/templates/param-types.tmpl
+++ b/pkg/codegen/templates/param-types.tmpl
@@ -1,6 +1,6 @@
 {{range .}}{{$opid := .OperationId}}
 {{range .TypeDefinitions}}
 // {{.TypeName}} defines parameters for {{$opid}}.
-type {{.TypeName}} {{.Schema.TypeDecl}}
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
 {{end}}
 {{end}}
diff --git a/pkg/codegen/templates/request-bodies.tmpl b/pkg/codegen/templates/request-bodies.tmpl
index cec74bc..313dd11 100644
--- a/pkg/codegen/templates/request-bodies.tmpl
+++ b/pkg/codegen/templates/request-bodies.tmpl
@@ -1,6 +1,8 @@
 {{range .}}{{$opid := .OperationId}}
 {{range .Bodies}}
-// {{$opid}}RequestBody defines body for {{$opid}} for application/json ContentType.
-type {{$opid}}{{.NameTag}}RequestBody {{.TypeDef}}
+{{with .TypeDef $opid}}
+// {{.TypeName}} defines body for {{$opid}} for application/json ContentType.
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
+{{end}}
 {{end}}
 {{end}}
diff --git a/pkg/codegen/templates/templates.gen.go b/pkg/codegen/templates/templates.gen.go
index d454970..4c0417a 100644
--- a/pkg/codegen/templates/templates.gen.go
+++ b/pkg/codegen/templates/templates.gen.go
@@ -642,6 +642,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
         return nil, err
     }
 
+    {{if .HasBody}}req.Header.Add("Content-Type", contentType){{end}}
 {{range $paramIdx, $param := .HeaderParams}}
     {{if not .Required}} if params.{{.GoName}} != nil { {{end}}
     var headerParam{{$paramIdx}} string
@@ -662,7 +663,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
         return nil, err
     }
     {{end}}
-    req.Header.Add("{{.ParamName}}", headerParam{{$paramIdx}})
+    req.Header.Set("{{.ParamName}}", headerParam{{$paramIdx}})
     {{if not .Required}}}{{end}}
 {{end}}
 
@@ -693,7 +694,6 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr
     req.AddCookie(cookie{{$paramIdx}})
     {{if not .Required}}}{{end}}
 {{end}}
-    {{if .HasBody}}req.Header.Add("Content-Type", contentType){{end}}
     return req, nil
 }
 
@@ -765,7 +765,7 @@ func GetSwagger() (*openapi3.Swagger, error) {
 	"param-types.tmpl": `{{range .}}{{$opid := .OperationId}}
 {{range .TypeDefinitions}}
 // {{.TypeName}} defines parameters for {{$opid}}.
-type {{.TypeName}} {{.Schema.TypeDecl}}
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
 {{end}}
 {{end}}
 `,
@@ -805,8 +805,10 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
 `,
 	"request-bodies.tmpl": `{{range .}}{{$opid := .OperationId}}
 {{range .Bodies}}
-// {{$opid}}RequestBody defines body for {{$opid}} for application/json ContentType.
-type {{$opid}}{{.NameTag}}RequestBody {{.TypeDef}}
+{{with .TypeDef $opid}}
+// {{.TypeName}} defines body for {{$opid}} for application/json ContentType.
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
+{{end}}
 {{end}}
 {{end}}
 `,
@@ -820,7 +822,7 @@ type ServerInterface interface {
 `,
 	"typedef.tmpl": `{{range .Types}}
 // {{.TypeName}} defines model for {{.JsonName}}.
-type {{.TypeName}} {{.Schema.TypeDecl}}
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
 {{- if gt (len .Schema.EnumValues) 0 }}
 // List of {{ .TypeName }}
 const (
diff --git a/pkg/codegen/templates/typedef.tmpl b/pkg/codegen/templates/typedef.tmpl
index 170984f..969d7cd 100644
--- a/pkg/codegen/templates/typedef.tmpl
+++ b/pkg/codegen/templates/typedef.tmpl
@@ -1,6 +1,6 @@
 {{range .Types}}
 // {{.TypeName}} defines model for {{.JsonName}}.
-type {{.TypeName}} {{.Schema.TypeDecl}}
+type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
 {{- if gt (len .Schema.EnumValues) 0 }}
 // List of {{ .TypeName }}
 const (
diff --git a/pkg/runtime/styleparam.go b/pkg/runtime/styleparam.go
index 84f2f31..30c285a 100644
--- a/pkg/runtime/styleparam.go
+++ b/pkg/runtime/styleparam.go
@@ -23,6 +23,8 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
+
+	"github.com/deepmap/oapi-codegen/pkg/types"
 )
 
 // Given an input value, such as a primitive type, array or object, turn it
@@ -134,22 +136,29 @@ func sortedKeys(strMap map[string]string) []string {
 	return keys
 }
 
-// This is a special case. The struct may be a time, in which case, marshal
-// it in RFC3339 format.
-func marshalTimeValue(value interface{}) (string, bool) {
-	if timeVal, ok := value.(*time.Time); ok {
+// This is a special case. The struct may be a date or time, in
+// which case, marshal it in correct format.
+func marshalDateTimeValue(value interface{}) (string, bool) {
+	v := reflect.Indirect(reflect.ValueOf(value))
+	t := v.Type()
+
+	if t.ConvertibleTo(reflect.TypeOf(time.Time{})) {
+		tt := v.Convert(reflect.TypeOf(time.Time{}))
+		timeVal := tt.Interface().(time.Time)
 		return timeVal.Format(time.RFC3339Nano), true
 	}
 
-	if timeVal, ok := value.(time.Time); ok {
-		return timeVal.Format(time.RFC3339Nano), true
+	if t.ConvertibleTo(reflect.TypeOf(types.Date{})) {
+		d := v.Convert(reflect.TypeOf(types.Date{}))
+		dateVal := d.Interface().(types.Date)
+		return dateVal.Format(types.DateFormat), true
 	}
 
 	return "", false
 }
 
 func styleStruct(style string, explode bool, paramName string, value interface{}) (string, error) {
-	if timeVal, ok := marshalTimeValue(value); ok {
+	if timeVal, ok := marshalDateTimeValue(value); ok {
 		styledVal, err := stylePrimitive(style, explode, paramName, url.QueryEscape(timeVal))
 		if err != nil {
 			return "", errors.Wrap(err, "failed to style time")


Test patch:
diff --git a/internal/test/client/client.gen.go b/internal/test/client/client.gen.go
index 41cd7f0..656f06e 100644
--- a/internal/test/client/client.gen.go
+++ b/internal/test/client/client.gen.go
@@ -32,10 +32,10 @@ type PostBothJSONBody SchemaObject
 // PostJsonJSONBody defines parameters for PostJson.
 type PostJsonJSONBody SchemaObject
 
-// PostBothRequestBody defines body for PostBoth for application/json ContentType.
+// PostBothJSONRequestBody defines body for PostBoth for application/json ContentType.
 type PostBothJSONRequestBody PostBothJSONBody
 
-// PostJsonRequestBody defines body for PostJson for application/json ContentType.
+// PostJsonJSONRequestBody defines body for PostJson for application/json ContentType.
 type PostJsonJSONRequestBody PostJsonJSONBody
 
 // RequestEditorFn  is the function signature for the RequestEditor callback function
@@ -308,6 +308,7 @@ func NewPostBothRequestWithBody(server string, contentType string, body io.Reade
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
@@ -374,6 +375,7 @@ func NewPostJsonRequestWithBody(server string, contentType string, body io.Reade
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
@@ -429,6 +431,7 @@ func NewPostOtherRequestWithBody(server string, contentType string, body io.Read
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go
index eda0b1a..6b28296 100644
--- a/internal/test/components/components.gen.go
+++ b/internal/test/components/components.gen.go
@@ -118,10 +118,10 @@ type BodyWithAddPropsJSONBody_Inner struct {
 	AdditionalProperties map[string]int `json:"-"`
 }
 
-// EnsureEverythingIsReferencedRequestBody defines body for EnsureEverythingIsReferenced for application/json ContentType.
+// EnsureEverythingIsReferencedJSONRequestBody defines body for EnsureEverythingIsReferenced for application/json ContentType.
 type EnsureEverythingIsReferencedJSONRequestBody RequestBody
 
-// BodyWithAddPropsRequestBody defines body for BodyWithAddProps for application/json ContentType.
+// BodyWithAddPropsJSONRequestBody defines body for BodyWithAddProps for application/json ContentType.
 type BodyWithAddPropsJSONRequestBody BodyWithAddPropsJSONBody
 
 // Getter for additional properties for ParamsWithAddPropsParams_P1. Returns the specified
@@ -918,6 +918,7 @@ func NewEnsureEverythingIsReferencedRequestWithBody(server string, contentType s
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
@@ -1012,6 +1013,7 @@ func NewBodyWithAddPropsRequestWithBody(server string, contentType string, body
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go
index c8e1fc4..5e3d4ce 100644
--- a/internal/test/issues/issue-grab_import_names/issue.gen.go
+++ b/internal/test/issues/issue-grab_import_names/issue.gen.go
@@ -154,7 +154,7 @@ func NewGetFooRequest(server string, params *GetFooParams) (*http.Request, error
 			return nil, err
 		}
 
-		req.Header.Add("Foo", headerParam0)
+		req.Header.Set("Foo", headerParam0)
 	}
 
 	if params.Bar != nil {
@@ -165,7 +165,7 @@ func NewGetFooRequest(server string, params *GetFooParams) (*http.Request, error
 			return nil, err
 		}
 
-		req.Header.Add("Bar", headerParam1)
+		req.Header.Set("Bar", headerParam1)
 	}
 
 	return req, nil
diff --git a/internal/test/parameters/parameters.gen.go b/internal/test/parameters/parameters.gen.go
index f0dfe05..9f3f096 100644
--- a/internal/test/parameters/parameters.gen.go
+++ b/internal/test/parameters/parameters.gen.go
@@ -733,7 +733,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Primitive", headerParam0)
+		req.Header.Set("X-Primitive", headerParam0)
 	}
 
 	if params.XPrimitiveExploded != nil {
@@ -744,7 +744,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Primitive-Exploded", headerParam1)
+		req.Header.Set("X-Primitive-Exploded", headerParam1)
 	}
 
 	if params.XArrayExploded != nil {
@@ -755,7 +755,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Array-Exploded", headerParam2)
+		req.Header.Set("X-Array-Exploded", headerParam2)
 	}
 
 	if params.XArray != nil {
@@ -766,7 +766,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Array", headerParam3)
+		req.Header.Set("X-Array", headerParam3)
 	}
 
 	if params.XObjectExploded != nil {
@@ -777,7 +777,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Object-Exploded", headerParam4)
+		req.Header.Set("X-Object-Exploded", headerParam4)
 	}
 
 	if params.XObject != nil {
@@ -788,7 +788,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 			return nil, err
 		}
 
-		req.Header.Add("X-Object", headerParam5)
+		req.Header.Set("X-Object", headerParam5)
 	}
 
 	if params.XComplexObject != nil {
@@ -801,7 +801,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request,
 		}
 		headerParam6 = string(headerParamBuf6)
 
-		req.Header.Add("X-Complex-Object", headerParam6)
+		req.Header.Set("X-Complex-Object", headerParam6)
 	}
 
 	return req, nil
diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go
index f628d7c..6a6d198 100644
--- a/internal/test/schemas/schemas.gen.go
+++ b/internal/test/schemas/schemas.gen.go
@@ -61,10 +61,10 @@ type Issue9Params struct {
 	Foo string `json:"foo"`
 }
 
-// Issue185RequestBody defines body for Issue185 for application/json ContentType.
+// Issue185JSONRequestBody defines body for Issue185 for application/json ContentType.
 type Issue185JSONRequestBody Issue185JSONBody
 
-// Issue9RequestBody defines body for Issue9 for application/json ContentType.
+// Issue9JSONRequestBody defines body for Issue9 for application/json ContentType.
 type Issue9JSONRequestBody Issue9JSONBody
 
 // RequestEditorFn  is the function signature for the RequestEditor callback function
@@ -391,6 +391,7 @@ func NewIssue185RequestWithBody(server string, contentType string, body io.Reade
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
@@ -548,6 +549,7 @@ func NewIssue9RequestWithBody(server string, params *Issue9Params, contentType s
 	}
 
 	req.Header.Add("Content-Type", contentType)
+
 	return req, nil
 }
 
diff --git a/internal/test/server/server.gen.go b/internal/test/server/server.gen.go
index d11434b..a64db8b 100644
--- a/internal/test/server/server.gen.go
+++ b/internal/test/server/server.gen.go
@@ -117,13 +117,13 @@ type UpdateResource3JSONBody struct {
 	Name *string `json:"name,omitempty"`
 }
 
-// CreateResourceRequestBody defines body for CreateResource for application/json ContentType.
+// CreateResourceJSONRequestBody defines body for CreateResource for application/json ContentType.
 type CreateResourceJSONRequestBody CreateResourceJSONBody
 
-// CreateResource2RequestBody defines body for CreateResource2 for application/json ContentType.
+// CreateResource2JSONRequestBody defines body for CreateResource2 for application/json ContentType.
 type CreateResource2JSONRequestBody CreateResource2JSONBody
 
-// UpdateResource3RequestBody defines body for UpdateResource3 for application/json ContentType.
+// UpdateResource3JSONRequestBody defines body for UpdateResource3 for application/json ContentType.
 type UpdateResource3JSONRequestBody UpdateResource3JSONBody
 
 // ServerInterface represents all server handlers.
diff --git a/pkg/runtime/styleparam_test.go b/pkg/runtime/styleparam_test.go
index fcf4eef..de3791a 100644
--- a/pkg/runtime/styleparam_test.go
+++ b/pkg/runtime/styleparam_test.go
@@ -18,6 +18,8 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/assert"
+
+	"github.com/deepmap/oapi-codegen/pkg/types"
 )
 
 func TestStyleParam(t *testing.T) {
@@ -34,7 +36,13 @@ func TestStyleParam(t *testing.T) {
 	dict := map[string]interface{}{}
 	dict["firstName"] = "Alex"
 	dict["role"] = "admin"
-	timestamp, _ := time.Parse(time.RFC3339, "2020-01-01T22:00:00+02:00")
+
+	type AliasedTime time.Time
+	ti, _ := time.Parse(time.RFC3339, "2020-01-01T22:00:00+02:00")
+	timestamp := AliasedTime(ti)
+
+	type AliasedDate types.Date
+	date := AliasedDate{time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)}
 
 	// ---------------------------- Simple Style -------------------------------
 
@@ -86,6 +94,22 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, "2020-01-01T22%3A00%3A00%2B02%3A00", result)
 
+	result, err = StyleParam("simple", false, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "2020-01-01", result)
+
+	result, err = StyleParam("simple", true, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "2020-01-01", result)
+
+	result, err = StyleParam("simple", false, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "2020-01-01", result)
+
+	result, err = StyleParam("simple", true, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "2020-01-01", result)
+
 	// ----------------------------- Label Style -------------------------------
 
 	result, err = StyleParam("label", false, "id", primitive)
@@ -136,6 +160,22 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, ".2020-01-01T22%3A00%3A00%2B02%3A00", result)
 
+	result, err = StyleParam("label", false, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ".2020-01-01", result)
+
+	result, err = StyleParam("label", true, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ".2020-01-01", result)
+
+	result, err = StyleParam("label", false, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ".2020-01-01", result)
+
+	result, err = StyleParam("label", true, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ".2020-01-01", result)
+
 	// ----------------------------- Matrix Style ------------------------------
 
 	result, err = StyleParam("matrix", false, "id", primitive)
@@ -186,6 +226,22 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, ";id=2020-01-01T22%3A00%3A00%2B02%3A00", result)
 
+	result, err = StyleParam("matrix", false, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ";id=2020-01-01", result)
+
+	result, err = StyleParam("matrix", true, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ";id=2020-01-01", result)
+
+	result, err = StyleParam("matrix", false, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ";id=2020-01-01", result)
+
+	result, err = StyleParam("matrix", true, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, ";id=2020-01-01", result)
+
 	// ------------------------------ Form Style -------------------------------
 	result, err = StyleParam("form", false, "id", primitive)
 	assert.NoError(t, err)
@@ -235,6 +291,22 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, "id=2020-01-01T22%3A00%3A00%2B02%3A00", result)
 
+	result, err = StyleParam("form", false, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "id=2020-01-01", result)
+
+	result, err = StyleParam("form", true, "id", date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "id=2020-01-01", result)
+
+	result, err = StyleParam("form", false, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "id=2020-01-01", result)
+
+	result, err = StyleParam("form", true, "id", &date)
+	assert.NoError(t, err)
+	assert.EqualValues(t, "id=2020-01-01", result)
+
 	// ------------------------  spaceDelimited Style --------------------------
 
 	result, err = StyleParam("spaceDelimited", false, "id", primitive)
@@ -275,6 +347,18 @@ func TestStyleParam(t *testing.T) {
 	result, err = StyleParam("spaceDelimited", true, "id", &timestamp)
 	assert.Error(t, err)
 
+	result, err = StyleParam("spaceDelimited", false, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("spaceDelimited", true, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("spaceDelimited", false, "id", &date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("spaceDelimited", true, "id", &date)
+	assert.Error(t, err)
+
 	// -------------------------  pipeDelimited Style --------------------------
 
 	result, err = StyleParam("pipeDelimited", false, "id", primitive)
@@ -315,6 +399,18 @@ func TestStyleParam(t *testing.T) {
 	result, err = StyleParam("pipeDelimited", true, "id", &timestamp)
 	assert.Error(t, err)
 
+	result, err = StyleParam("pipeDelimited", false, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("pipeDelimited", true, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("pipeDelimited", false, "id", &date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("pipeDelimited", true, "id", &date)
+	assert.Error(t, err)
+
 	// ---------------------------  deepObject Style ---------------------------
 	result, err = StyleParam("deepObject", false, "id", primitive)
 	assert.Error(t, err)
@@ -352,6 +448,18 @@ func TestStyleParam(t *testing.T) {
 	result, err = StyleParam("deepObject", true, "id", &timestamp)
 	assert.Error(t, err)
 
+	result, err = StyleParam("deepObject", false, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("deepObject", true, "id", date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("deepObject", false, "id", &date)
+	assert.Error(t, err)
+
+	result, err = StyleParam("deepObject", true, "id", &date)
+	assert.Error(t, err)
+
 	// Misc tests
 	// Test type aliases
 	type StrType string