Skip to content

Commit

Permalink
Merge pull request nytimes#122 from nytimes/global-responses
Browse files Browse the repository at this point in the history
Adding the ability to use a global 'responses' object.
  • Loading branch information
jprobinson authored Dec 5, 2019
2 parents dc580a8 + 54d2763 commit 9657212
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
28 changes: 28 additions & 0 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ func Compile(spec *openapi.Spec, options ...Option) (*protobuf.Package, error) {
if err := c.compileParameters(spec.Parameters); err != nil {
return nil, errors.Wrap(err, `failed to compile parameters`)
}
if err := c.compileResponses(spec.Responses); err != nil {
return nil, errors.Wrap(err, `failed to compile global responses`)
}

p2, err := protobuf.Resolve(c.pkg, c.getTypeFromReference)
if err != nil {
Expand Down Expand Up @@ -222,6 +225,24 @@ func (c *compileCtx) compileParameters(parameters map[string]*openapi.Parameter)
return nil
}

// Note: compiles GLOBAL responses. not to be used for compiling
// actual endpoint responses
func (c *compileCtx) compileResponses(responses map[string]*openapi.Response) error {
c.phase = phaseCompileDefinitions
for name, response := range responses {
if response.Schema == nil {
c.addDefinition("#/responses/"+name, protobuf.NewMessage(name))
continue
}
m, err := c.compileSchema(camelCase(name), response.Schema)
if err != nil {
return errors.Wrapf(err, `failed to compile #/parameters/%s`, name)
}
c.addDefinition("#/responses/"+name, m)
}
return nil
}

func (c *compileCtx) compileExtension(ext *openapi.Extension) (*protobuf.Extension, error) {
e := protobuf.NewExtension(ext.Base)
for _, f := range ext.Fields {
Expand Down Expand Up @@ -333,6 +354,7 @@ func (c *compileCtx) compilePath(path string, p *openapi.Path) error {
if !ok {
continue
}

resName := endpointName + "Response"
if resp.Schema != nil {
// Wow, this *sucks*! We need to special-case when resp.Schema
Expand All @@ -357,6 +379,12 @@ func (c *compileCtx) compilePath(path string, p *openapi.Path) error {
}
resType = typ
}
} else if resp.Ref != "" {
typ, err := c.getTypeFromReference(resp.Ref)
if err != nil {
return errors.Wrapf(err, `failed to look up response ref for %s`, endpointName)
}
resType = typ
}

if resType != nil {
Expand Down
20 changes: 20 additions & 0 deletions fixtures/global_responses.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";

package example;

message ExampleOperationRequest {
ExampleRequest body = 1;
}

message ExampleRequest {
string example = 1;
}

message ExampleResponse {
string anotherExample = 1;
}

service ExampleService {
// Example operation
rpc ExampleOperation(ExampleOperationRequest) returns (ExampleResponse) {}
}
39 changes: 39 additions & 0 deletions fixtures/global_responses.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
swagger: "2.0"

info:
title: example
description: An example API to demonstrate issue in responses
version: 1.0.0
paths:
/example:
post:
operationId: exampleOperation
description: Example operation
parameters:
- in: body
name: body
schema:
$ref: '#/definitions/ExampleRequest'
responses:
200:
$ref: '#/responses/ExampleResponse'
400:
$ref: '#/responses/BadRequest'
definitions:
ExampleRequest:
type: object
required:
- example
properties:
example:
type: string
responses:
ExampleResponse:
description: Example response
schema:
type: object
properties:
anotherExample:
type: string
BadRequest:
description: Bad request
2 changes: 2 additions & 0 deletions openapi/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Spec struct {
Produces []string `yaml:"produces" json:"produces"`
Paths map[string]*Path `yaml:"paths" json:"paths"`
Definitions map[string]*Schema `yaml:"definitions" json:"definitions"`
Responses map[string]*Response `yaml:"responses" json:"responses"`
Parameters map[string]*Parameter `yaml:"parameters" json:"parameters"`
Extensions []*Extension `yaml:"x-extensions" json:"x-extensions"`
GlobalOptions GlobalOptions `yaml:"x-global-options" json:"x-global-options"`
Expand Down Expand Up @@ -98,6 +99,7 @@ type Parameters []*Parameter
type Response struct {
Description string `yaml:"description" json:"description"`
Schema *Schema `yaml:"schema" json:"schema"`
Ref string `yaml:"$ref" json:"$ref"`
}

// Endpoint represents an endpoint for a path in an OpenAPI spec.
Expand Down
3 changes: 3 additions & 0 deletions proto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ func TestGenerateProto(t *testing.T) {
addAutogeneratedComment: true,
fixturePath: "fixtures/add_autogenerated_comment.yaml",
},
{
fixturePath: "fixtures/global_responses.yaml",
},
}
testGenProto(t, tests...)
}

0 comments on commit 9657212

Please sign in to comment.