[protoc-gen-openapiv2] Incorrectly generated OpenAPIv2 spec when using field_behaviour annotation
#3058 opened on Dec 12, 2022
Description
🐛 Bug Report
This is almost exactly the same error as in #1937:
With the introduction of https://github.com/grpc-ecosystem/grpc-gateway/pull/1806 rpc definitions definitions that have a non-wildcard body property now fail validation. The generated code breaks because it produces a swagger document whose body parameter is a reference to the request definition but also has a required entry in the object.
Note that this file swagger file failed npx @opernapitools/openapi-generator-cli generate with error saying that required is unexpected.
The #1937 is already resolved & closed but it seems this type of error was not resolved completely since I can reproduce it.
To Reproduce
I'm using Buf to deal with external dependencies (googleapis). But you should be able to reproduce it using only protoc, protoc-gen-openapiv2 and foo.proto, if you manually provide the googleapis.
Here's the whole Buf setup:
.
├── buf.gen.yaml
├── buf.work.yaml
└── proto
├── buf.lock
├── buf.yaml
└── v1
└── foo.proto
buf.gen.yaml
version: v1
managed:
enabled: true
go_package_prefix:
default: github.com/foo
plugins:
- name: openapiv2
out: gen
buf.work.yaml
version: v1
directories:
- proto
proto/buf.yaml
version: v1
deps:
- buf.build/googleapis/googleapis
proto/buf.lock
Is generated by command:
cd proto && buf mod update
example content:
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: faacf837d7304c58b7c9020c7807fa6e
proto/v1/foo.proto
syntax = "proto3";
package v1;
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
message Foo {
}
message CreateFooRequest{
Foo foo = 1 [(google.api.field_behavior) = REQUIRED];
}
service FooService {
rpc CreateFoo (CreateFooRequest) returns (Foo) {
option (google.api.http) = {
post: "/v1/foos"
body: "foo"
};
}
}
Finally, generate openapiv2 via buf command:
buf generate
(you should be also able to generate directly by using protoc but you have to provide the googleapis deps)
Expected behavior
gen/v1/foo.swagger.json
{
"swagger": "2.0",
"info": {
"title": "v1/foo.proto",
"version": "version not set"
},
"tags": [
{
"name": "FooService"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/v1/foos": {
"post": {
"operationId": "FooService_CreateFoo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1Foo"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "foo",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1Foo",
}
}
],
"tags": [
"FooService"
]
}
}
},
"definitions": {
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"v1Foo": {
"type": "object"
}
}
}
Actual Behavior
gen/v1/foo.swagger.json
{
"swagger": "2.0",
"info": {
"title": "v1/foo.proto",
"version": "version not set"
},
"tags": [
{
"name": "FooService"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/v1/foos": {
"post": {
"operationId": "FooService_CreateFoo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1Foo"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "foo",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1Foo",
"required": [ <-- THIS SHOULDN'T BE HERE
"foo"
]
}
}
],
"tags": [
"FooService"
]
}
}
},
"definitions": {
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"v1Foo": {
"type": "object"
}
}
}
Your Environment
buf version: 1.10.0 protoc-gen-openapiv2 version: v2.14.0 go version: go1.19.1 darwin/amd64