From 8df1bbfa9ff3caa0137f418fed606c74807b4555 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Mon, 21 Sep 2020 16:12:21 -0400 Subject: [PATCH 1/3] Split the response types out --- pkg/codegen/template_helpers.go | 6 +++--- pkg/codegen/templates/client-with-responses.tmpl | 6 +++++- pkg/codegen/templates/templates.gen.go | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 7c46ec2d06..b6a88dbcc4 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -155,7 +155,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { " return nil, err \n"+ "}\n"+ "response.%s = &dest", - typeDefinition.Schema.TypeDecl(), + op.OperationId+"Response"+typeDefinition.TypeName, typeDefinition.TypeName) caseKey, caseClause := buildUnmarshalCase(typeDefinition, caseAction, "json") @@ -169,7 +169,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { " return nil, err \n"+ "}\n"+ "response.%s = &dest", - typeDefinition.Schema.TypeDecl(), + op.OperationId+"Response"+typeDefinition.TypeName, typeDefinition.TypeName) caseKey, caseClause := buildUnmarshalCase(typeDefinition, caseAction, "yaml") handledCaseClauses[caseKey] = caseClause @@ -182,7 +182,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { " return nil, err \n"+ "}\n"+ "response.%s = &dest", - typeDefinition.Schema.TypeDecl(), + op.OperationId+"Response"+typeDefinition.TypeName, typeDefinition.TypeName) caseKey, caseClause := buildUnmarshalCase(typeDefinition, caseAction, "xml") handledCaseClauses[caseKey] = caseClause diff --git a/pkg/codegen/templates/client-with-responses.tmpl b/pkg/codegen/templates/client-with-responses.tmpl index 0ea7683037..d37b33aee5 100644 --- a/pkg/codegen/templates/client-with-responses.tmpl +++ b/pkg/codegen/templates/client-with-responses.tmpl @@ -40,11 +40,15 @@ type ClientWithResponsesInterface interface { } {{range .}}{{$opid := .OperationId}}{{$op := .}} +{{- range getResponseTypeDefinitions .}} +// {{$opid}}Response{{.TypeName}} represents a possible response for the {{$opid}} request. +type {{$opid}}Response{{.TypeName}} {{.Schema.TypeDecl}} +{{- end}} type {{$opid | ucFirst}}Response struct { Body []byte HTTPResponse *http.Response {{- range getResponseTypeDefinitions .}} - {{.TypeName}} *{{.Schema.TypeDecl}} + {{.TypeName}} *{{$opid}}Response{{.TypeName}} {{- end}} } diff --git a/pkg/codegen/templates/templates.gen.go b/pkg/codegen/templates/templates.gen.go index 770ba76fd4..f4a6a7b177 100644 --- a/pkg/codegen/templates/templates.gen.go +++ b/pkg/codegen/templates/templates.gen.go @@ -309,11 +309,15 @@ type ClientWithResponsesInterface interface { } {{range .}}{{$opid := .OperationId}}{{$op := .}} +{{- range getResponseTypeDefinitions .}} +// {{$opid}}Response{{.TypeName}} represents a possible response for the {{$opid}} request. +type {{$opid}}Response{{.TypeName}} {{.Schema.TypeDecl}} +{{- end}} type {{$opid | ucFirst}}Response struct { Body []byte HTTPResponse *http.Response {{- range getResponseTypeDefinitions .}} - {{.TypeName}} *{{.Schema.TypeDecl}} + {{.TypeName}} *{{$opid}}Response{{.TypeName}} {{- end}} } From 8efef008f522a9132a6a618d38d8d71c52498c05 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Mon, 21 Sep 2020 16:12:47 -0400 Subject: [PATCH 2/3] Re-generate and fix tests --- .../petstore-expanded/petstore-client.gen.go | 45 +++++++++---- internal/test/components/components.gen.go | 66 ++++++++----------- internal/test/issues/issue-52/issue.gen.go | 6 +- .../issue-grab_import_names/issue.gen.go | 6 +- .../issue-illegal_enum_names/issue.gen.go | 6 +- internal/test/schemas/schemas.gen.go | 51 +++++++------- pkg/codegen/codegen_test.go | 10 +-- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/examples/petstore-expanded/petstore-client.gen.go b/examples/petstore-expanded/petstore-client.gen.go index 7f562d8cc9..cdb8790e51 100644 --- a/examples/petstore-expanded/petstore-client.gen.go +++ b/examples/petstore-expanded/petstore-client.gen.go @@ -438,11 +438,16 @@ type ClientWithResponsesInterface interface { FindPetByIdWithResponse(ctx context.Context, id int64) (*FindPetByIdResponse, error) } +// FindPetsResponseJSON200 represents a possible response for the FindPets request. +type FindPetsResponseJSON200 []Pet + +// FindPetsResponseJSONDefault represents a possible response for the FindPets request. +type FindPetsResponseJSONDefault Error type FindPetsResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *[]Pet - JSONDefault *Error + JSON200 *FindPetsResponseJSON200 + JSONDefault *FindPetsResponseJSONDefault } // Status returns HTTPResponse.Status @@ -461,11 +466,16 @@ func (r FindPetsResponse) StatusCode() int { return 0 } +// AddPetResponseJSON200 represents a possible response for the AddPet request. +type AddPetResponseJSON200 Pet + +// AddPetResponseJSONDefault represents a possible response for the AddPet request. +type AddPetResponseJSONDefault Error type AddPetResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Pet - JSONDefault *Error + JSON200 *AddPetResponseJSON200 + JSONDefault *AddPetResponseJSONDefault } // Status returns HTTPResponse.Status @@ -484,10 +494,12 @@ func (r AddPetResponse) StatusCode() int { return 0 } +// DeletePetResponseJSONDefault represents a possible response for the DeletePet request. +type DeletePetResponseJSONDefault Error type DeletePetResponse struct { Body []byte HTTPResponse *http.Response - JSONDefault *Error + JSONDefault *DeletePetResponseJSONDefault } // Status returns HTTPResponse.Status @@ -506,11 +518,16 @@ func (r DeletePetResponse) StatusCode() int { return 0 } +// FindPetByIdResponseJSON200 represents a possible response for the FindPetById request. +type FindPetByIdResponseJSON200 Pet + +// FindPetByIdResponseJSONDefault represents a possible response for the FindPetById request. +type FindPetByIdResponseJSONDefault Error type FindPetByIdResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Pet - JSONDefault *Error + JSON200 *FindPetByIdResponseJSON200 + JSONDefault *FindPetByIdResponseJSONDefault } // Status returns HTTPResponse.Status @@ -588,14 +605,14 @@ func ParseFindPetsResponse(rsp *http.Response) (*FindPetsResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest []Pet + var dest FindPetsResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest Error + var dest FindPetsResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -621,14 +638,14 @@ func ParseAddPetResponse(rsp *http.Response) (*AddPetResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Pet + var dest AddPetResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest Error + var dest AddPetResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -654,7 +671,7 @@ func ParseDeletePetResponse(rsp *http.Response) (*DeletePetResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest Error + var dest DeletePetResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -680,14 +697,14 @@ func ParseFindPetByIdResponse(rsp *http.Response) (*FindPetByIdResponse, error) switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Pet + var dest FindPetByIdResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest Error + var dest FindPetByIdResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go index 222b4c25d5..5896d95d8e 100644 --- a/internal/test/components/components.gen.go +++ b/internal/test/components/components.gen.go @@ -1056,30 +1056,35 @@ type ClientWithResponsesInterface interface { BodyWithAddPropsWithResponse(ctx context.Context, body BodyWithAddPropsJSONRequestBody) (*BodyWithAddPropsResponse, error) } -type EnsureEverythingIsReferencedResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *struct { +// EnsureEverythingIsReferencedResponseJSON200 represents a possible response for the EnsureEverythingIsReferenced request. +type EnsureEverythingIsReferencedResponseJSON200 struct { - // Has additional properties with schema for dictionaries - Five *AdditionalPropertiesObject5 `json:"five,omitempty"` + // Has additional properties with schema for dictionaries + Five *AdditionalPropertiesObject5 `json:"five,omitempty"` - // Has anonymous field which has additional properties - Four *AdditionalPropertiesObject4 `json:"four,omitempty"` - JsonField *ObjectWithJsonField `json:"jsonField,omitempty"` + // Has anonymous field which has additional properties + Four *AdditionalPropertiesObject4 `json:"four,omitempty"` + JsonField *ObjectWithJsonField `json:"jsonField,omitempty"` - // Has additional properties of type int - One *AdditionalPropertiesObject1 `json:"one,omitempty"` + // Has additional properties of type int + One *AdditionalPropertiesObject1 `json:"one,omitempty"` - // Allows any additional property - Three *AdditionalPropertiesObject3 `json:"three,omitempty"` + // Allows any additional property + Three *AdditionalPropertiesObject3 `json:"three,omitempty"` - // Does not allow additional properties - Two *AdditionalPropertiesObject2 `json:"two,omitempty"` - } - JSONDefault *struct { - Field SchemaObject `json:"Field"` - } + // Does not allow additional properties + Two *AdditionalPropertiesObject2 `json:"two,omitempty"` +} + +// EnsureEverythingIsReferencedResponseJSONDefault represents a possible response for the EnsureEverythingIsReferenced request. +type EnsureEverythingIsReferencedResponseJSONDefault struct { + Field SchemaObject `json:"Field"` +} +type EnsureEverythingIsReferencedResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *EnsureEverythingIsReferencedResponseJSON200 + JSONDefault *EnsureEverythingIsReferencedResponseJSONDefault } // Status returns HTTPResponse.Status @@ -1198,33 +1203,14 @@ func ParseEnsureEverythingIsReferencedResponse(rsp *http.Response) (*EnsureEvery switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest struct { - - // Has additional properties with schema for dictionaries - Five *AdditionalPropertiesObject5 `json:"five,omitempty"` - - // Has anonymous field which has additional properties - Four *AdditionalPropertiesObject4 `json:"four,omitempty"` - JsonField *ObjectWithJsonField `json:"jsonField,omitempty"` - - // Has additional properties of type int - One *AdditionalPropertiesObject1 `json:"one,omitempty"` - - // Allows any additional property - Three *AdditionalPropertiesObject3 `json:"three,omitempty"` - - // Does not allow additional properties - Two *AdditionalPropertiesObject2 `json:"two,omitempty"` - } + var dest EnsureEverythingIsReferencedResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest struct { - Field SchemaObject `json:"Field"` - } + var dest EnsureEverythingIsReferencedResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go index 33ef17219a..512f8c2491 100644 --- a/internal/test/issues/issue-52/issue.gen.go +++ b/internal/test/issues/issue-52/issue.gen.go @@ -242,10 +242,12 @@ type ClientWithResponsesInterface interface { ExampleGetWithResponse(ctx context.Context) (*ExampleGetResponse, error) } +// ExampleGetResponseJSON200 represents a possible response for the ExampleGet request. +type ExampleGetResponseJSON200 Document type ExampleGetResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Document + JSON200 *ExampleGetResponseJSON200 } // Status returns HTTPResponse.Status @@ -288,7 +290,7 @@ func ParseExampleGetResponse(rsp *http.Response) (*ExampleGetResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Document + var dest ExampleGetResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } 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 035f47bf4c..874c7ecea2 100644 --- a/internal/test/issues/issue-grab_import_names/issue.gen.go +++ b/internal/test/issues/issue-grab_import_names/issue.gen.go @@ -202,10 +202,12 @@ type ClientWithResponsesInterface interface { GetFooWithResponse(ctx context.Context, params *GetFooParams) (*GetFooResponse, error) } +// GetFooResponseJSON200 represents a possible response for the GetFoo request. +type GetFooResponseJSON200 string type GetFooResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *string + JSON200 *GetFooResponseJSON200 } // Status returns HTTPResponse.Status @@ -248,7 +250,7 @@ func ParseGetFooResponse(rsp *http.Response) (*GetFooResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest string + var dest GetFooResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go index 8548802b80..00f5446ccd 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go +++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go @@ -184,10 +184,12 @@ type ClientWithResponsesInterface interface { GetFooWithResponse(ctx context.Context) (*GetFooResponse, error) } +// GetFooResponseJSON200 represents a possible response for the GetFoo request. +type GetFooResponseJSON200 []Bar type GetFooResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *[]Bar + JSON200 *GetFooResponseJSON200 } // Status returns HTTPResponse.Status @@ -230,7 +232,7 @@ func ParseGetFooResponse(rsp *http.Response) (*GetFooResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest []Bar + var dest GetFooResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index bab13e6479..d7c30f501d 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -604,16 +604,18 @@ type ClientWithResponsesInterface interface { Issue9WithResponse(ctx context.Context, params *Issue9Params, body Issue9JSONRequestBody) (*Issue9Response, error) } +// EnsureEverythingIsReferencedResponseJSON200 represents a possible response for the EnsureEverythingIsReferenced request. +type EnsureEverythingIsReferencedResponseJSON200 struct { + AnyType1 *AnyType1 `json:"anyType1,omitempty"` + + // This should be an interface{} + AnyType2 *AnyType2 `json:"anyType2,omitempty"` + CustomStringType *CustomStringType `json:"customStringType,omitempty"` +} type EnsureEverythingIsReferencedResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *struct { - AnyType1 *AnyType1 `json:"anyType1,omitempty"` - - // This should be an interface{} - AnyType2 *AnyType2 `json:"anyType2,omitempty"` - CustomStringType *CustomStringType `json:"customStringType,omitempty"` - } + JSON200 *EnsureEverythingIsReferencedResponseJSON200 } // Status returns HTTPResponse.Status @@ -632,13 +634,24 @@ func (r EnsureEverythingIsReferencedResponse) StatusCode() int { return 0 } +// Issue127ResponseJSON200 represents a possible response for the Issue127 request. +type Issue127ResponseJSON200 GenericObject + +// Issue127ResponseXML200 represents a possible response for the Issue127 request. +type Issue127ResponseXML200 GenericObject + +// Issue127ResponseYAML200 represents a possible response for the Issue127 request. +type Issue127ResponseYAML200 GenericObject + +// Issue127ResponseJSONDefault represents a possible response for the Issue127 request. +type Issue127ResponseJSONDefault GenericObject type Issue127Response struct { Body []byte HTTPResponse *http.Response - JSON200 *GenericObject - XML200 *GenericObject - YAML200 *GenericObject - JSONDefault *GenericObject + JSON200 *Issue127ResponseJSON200 + XML200 *Issue127ResponseXML200 + YAML200 *Issue127ResponseYAML200 + JSONDefault *Issue127ResponseJSONDefault } // Status returns HTTPResponse.Status @@ -856,13 +869,7 @@ func ParseEnsureEverythingIsReferencedResponse(rsp *http.Response) (*EnsureEvery switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest struct { - AnyType1 *AnyType1 `json:"anyType1,omitempty"` - - // This should be an interface{} - AnyType2 *AnyType2 `json:"anyType2,omitempty"` - CustomStringType *CustomStringType `json:"customStringType,omitempty"` - } + var dest EnsureEverythingIsReferencedResponseJSON200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -888,28 +895,28 @@ func ParseIssue127Response(rsp *http.Response) (*Issue127Response, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GenericObject + var dest Issue127ResponseYAML200 if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.YAML200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest GenericObject + var dest Issue127ResponseJSONDefault if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSONDefault = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "xml") && rsp.StatusCode == 200: - var dest GenericObject + var dest Issue127ResponseYAML200 if err := xml.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.YAML200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "yaml") && rsp.StatusCode == 200: - var dest GenericObject + var dest Issue127ResponseYAML200 if err := yaml.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/pkg/codegen/codegen_test.go b/pkg/codegen/codegen_test.go index a1a84d14ee..d6f3fdeade 100644 --- a/pkg/codegen/codegen_test.go +++ b/pkg/codegen/codegen_test.go @@ -146,11 +146,11 @@ func TestExampleOpenAPICodeGeneration(t *testing.T) { type GetTestByNameResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *[]Test - XML200 *[]Test - JSON422 *[]interface{} - XML422 *[]interface{} - JSONDefault *Error + JSON200 *GetTestByNameResponseJSON200 + XML200 *GetTestByNameResponseXML200 + JSON422 *GetTestByNameResponseJSON422 + XML422 *GetTestByNameResponseXML422 + JSONDefault *GetTestByNameResponseJSONDefault }`) // Check that the helper methods are generated correctly: From 0b13fb1ab75b24d20619ee350b11edfddacee5d2 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Tue, 25 May 2021 17:06:55 +0900 Subject: [PATCH 3/3] Alias the response type if needed --- pkg/codegen/templates/client-with-responses.tmpl | 2 +- pkg/codegen/templates/templates.gen.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/codegen/templates/client-with-responses.tmpl b/pkg/codegen/templates/client-with-responses.tmpl index 2fdcd4ff7a..58977c3d43 100644 --- a/pkg/codegen/templates/client-with-responses.tmpl +++ b/pkg/codegen/templates/client-with-responses.tmpl @@ -42,7 +42,7 @@ type ClientWithResponsesInterface interface { {{range .}}{{$opid := .OperationId}}{{$op := .}} {{- range getResponseTypeDefinitions .}} // {{$opid}}Response{{.TypeName}} represents a possible response for the {{$opid}} request. -type {{$opid}}Response{{.TypeName}} {{.Schema.TypeDecl}} +type {{$opid}}Response{{.TypeName}} {{if opts.AliasTypes}}= {{end}}{{.Schema.TypeDecl}} {{- end}} type {{$opid | ucFirst}}Response struct { Body []byte diff --git a/pkg/codegen/templates/templates.gen.go b/pkg/codegen/templates/templates.gen.go index dcc0ab5665..aeb0959f3f 100644 --- a/pkg/codegen/templates/templates.gen.go +++ b/pkg/codegen/templates/templates.gen.go @@ -351,7 +351,7 @@ type ClientWithResponsesInterface interface { {{range .}}{{$opid := .OperationId}}{{$op := .}} {{- range getResponseTypeDefinitions .}} // {{$opid}}Response{{.TypeName}} represents a possible response for the {{$opid}} request. -type {{$opid}}Response{{.TypeName}} {{.Schema.TypeDecl}} +type {{$opid}}Response{{.TypeName}} {{if opts.AliasTypes}}= {{end}}{{.Schema.TypeDecl}} {{- end}} type {{$opid | ucFirst}}Response struct { Body []byte