Skip to content

Commit

Permalink
make generated swagger json match gateway behavior for server streams (
Browse files Browse the repository at this point in the history
…#850)

* #579 fixing protoc-gen-swagger to wrap server stream messages with "result" object to match gateway behavior

* #579 fixing test example swagger json

* change streamdefinitions to x-stream-definitions and add test

* move runtime internal to root of repo for use in protoc-gen-swagger, adding error to stream wrapper

* adding comment explaining AddStreamError

* fix bazel
  • Loading branch information
mechinn authored and johanbrandhorst committed Jan 23, 2019
1 parent 9221822 commit f336fbc
Show file tree
Hide file tree
Showing 14 changed files with 586 additions and 45 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ SWAGGER_PLUGIN_FLAGS?=
GOOGLEAPIS_DIR=third_party/googleapis
OUTPUT_DIR=_output

RUNTIME_PROTO=runtime/internal/stream_chunk.proto
RUNTIME_PROTO=internal/stream_chunk.proto
RUNTIME_GO=$(RUNTIME_PROTO:.proto=.pb.go)

OPENAPIV2_PROTO=protoc-gen-swagger/options/openapiv2.proto protoc-gen-swagger/options/annotations.proto
Expand All @@ -63,6 +63,7 @@ endif
SWAGGER_EXAMPLES=examples/proto/examplepb/echo_service.proto \
examples/proto/examplepb/a_bit_of_everything.proto \
examples/proto/examplepb/wrappers.proto \
examples/proto/examplepb/stream.proto \
examples/proto/examplepb/unannotated_echo_service.proto \
examples/proto/examplepb/response_body_service.proto

Expand Down
362 changes: 362 additions & 0 deletions examples/proto/examplepb/stream.swagger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,362 @@
{
"swagger": "2.0",
"info": {
"title": "examples/proto/examplepb/stream.proto",
"version": "version not set"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/v1/example/a_bit_of_everything": {
"get": {
"operationId": "List",
"responses": {
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/examplepbABitOfEverything"
}
}
},
"tags": [
"StreamService"
]
}
},
"/v1/example/a_bit_of_everything/bulk": {
"post": {
"operationId": "BulkCreate",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"properties": {}
}
}
},
"parameters": [
{
"name": "body",
"description": " (streaming inputs)",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/examplepbABitOfEverything"
}
}
],
"tags": [
"StreamService"
]
}
},
"/v1/example/a_bit_of_everything/echo": {
"post": {
"operationId": "BulkEcho",
"responses": {
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/subStringMessage"
}
}
},
"parameters": [
{
"name": "body",
"description": " (streaming inputs)",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subStringMessage"
}
}
],
"tags": [
"StreamService"
]
}
}
},
"definitions": {
"ABitOfEverythingNested": {
"type": "object",
"example": {
"ok": "TRUE"
},
"properties": {
"name": {
"type": "string",
"description": "name is nested field."
},
"amount": {
"type": "integer",
"format": "int64"
},
"ok": {
"$ref": "#/definitions/NestedDeepEnum"
}
},
"description": "Nested is nested type."
},
"MessagePathEnumNestedPathEnum": {
"type": "string",
"enum": [
"GHI",
"JKL"
],
"default": "GHI"
},
"NestedDeepEnum": {
"type": "string",
"enum": [
"FALSE",
"TRUE"
],
"default": "FALSE",
"description": "DeepEnum is one or zero.\n\n - FALSE: FALSE is false.\n - TRUE: TRUE is true."
},
"examplepbABitOfEverything": {
"type": "object",
"example": {
"uuid": "0cf361e1-4b44-483d-a159-54dabdf7e814"
},
"properties": {
"single_nested": {
"$ref": "#/definitions/ABitOfEverythingNested"
},
"uuid": {
"type": "string",
"minLength": 1,
"pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
},
"nested": {
"type": "array",
"items": {
"$ref": "#/definitions/ABitOfEverythingNested"
}
},
"float_value": {
"type": "number",
"format": "float"
},
"double_value": {
"type": "number",
"format": "double"
},
"int64_value": {
"type": "string",
"format": "int64"
},
"uint64_value": {
"type": "string",
"format": "uint64"
},
"int32_value": {
"type": "integer",
"format": "int32"
},
"fixed64_value": {
"type": "string",
"format": "uint64"
},
"fixed32_value": {
"type": "integer",
"format": "int64"
},
"bool_value": {
"type": "boolean",
"format": "boolean"
},
"string_value": {
"type": "string"
},
"bytes_value": {
"type": "string",
"format": "byte"
},
"uint32_value": {
"type": "integer",
"format": "int64"
},
"enum_value": {
"$ref": "#/definitions/examplepbNumericEnum"
},
"path_enum_value": {
"$ref": "#/definitions/pathenumPathEnum"
},
"nested_path_enum_value": {
"$ref": "#/definitions/MessagePathEnumNestedPathEnum"
},
"sfixed32_value": {
"type": "integer",
"format": "int32"
},
"sfixed64_value": {
"type": "string",
"format": "int64"
},
"sint32_value": {
"type": "integer",
"format": "int32"
},
"sint64_value": {
"type": "string",
"format": "int64"
},
"repeated_string_value": {
"type": "array",
"items": {
"type": "string"
}
},
"oneof_empty": {
"properties": {}
},
"oneof_string": {
"type": "string"
},
"map_value": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/examplepbNumericEnum"
}
},
"mapped_string_value": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"mapped_nested_value": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ABitOfEverythingNested"
}
},
"nonConventionalNameValue": {
"type": "string"
},
"timestamp_value": {
"type": "string",
"format": "date-time"
},
"repeated_enum_value": {
"type": "array",
"items": {
"$ref": "#/definitions/examplepbNumericEnum"
},
"title": "repeated enum value. it is comma-separated in query"
}
},
"description": "Intentionaly complicated message type to cover many features of Protobuf.",
"title": "A bit of everything",
"externalDocs": {
"description": "Find out more about ABitOfEverything",
"url": "https://github.com/grpc-ecosystem/grpc-gateway"
},
"required": [
"uuid"
]
},
"examplepbNumericEnum": {
"type": "string",
"enum": [
"ZERO",
"ONE"
],
"default": "ZERO",
"description": "NumericEnum is one or zero.\n\n - ZERO: ZERO means 0\n - ONE: ONE means 1"
},
"pathenumPathEnum": {
"type": "string",
"enum": [
"ABC",
"DEF"
],
"default": "ABC"
},
"protobufAny": {
"type": "object",
"properties": {
"type_url": {
"type": "string",
"description": "A URL/resource name whose content describes the type of the\nserialized protocol buffer message.\n\nFor URLs which use the scheme `http`, `https`, or no scheme, the\nfollowing restrictions and interpretations apply:\n\n* If no scheme is provided, `https` is assumed.\n* The last segment of the URL's path must represent the fully\n qualified name of the type (as in `path/google.protobuf.Duration`).\n The name should be in a canonical form (e.g., leading \".\" is\n not accepted).\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics."
},
"value": {
"type": "string",
"format": "byte",
"description": "Must be a valid serialized protocol buffer of the above specified type."
}
},
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
},
"runtimeStreamError": {
"type": "object",
"properties": {
"grpc_code": {
"type": "integer",
"format": "int32"
},
"http_code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"http_status": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"subStringMessage": {
"type": "object",
"properties": {
"value": {
"type": "string"
}
}
}
},
"x-stream-definitions": {
"examplepbABitOfEverything": {
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/examplepbABitOfEverything"
},
"error": {
"$ref": "#/definitions/runtimeStreamError"
}
},
"title": "Stream result of examplepbABitOfEverything"
},
"subStringMessage": {
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/subStringMessage"
},
"error": {
"$ref": "#/definitions/runtimeStreamError"
}
},
"title": "Stream result of subStringMessage"
}
}
}
Loading

0 comments on commit f336fbc

Please sign in to comment.