-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[protoc-gen-openapiv2] Incorrectly generated OpenAPIv2 spec when using field_behaviour annotation #3058
Comments
Thanks for the detailed issue, and I'm sorry this is causing trouble for you. It seems to me there might only be a minor additional fix to the original fix, would you be interested in pursuing it? The first step would probably be to add an example of this problem to our monster example protobuf file, then we could work on correcting the behavior. |
Hi, yes, I can try to fix that. I've added the I'll try to fix it analogically as was done in #1944. |
This turned out more difficult than expected. The main problem is that it is not clear how the Reference Object ContextThe OpenAPI v2 spec defines Reference Object:
The linked JSON Reference definition mentions:
As I understand it, this definition does not explicitly forbid other members (siblings) of the ref object. It only says, that other members shall be ignored; so the actual behaviour I put into issue description may be "kind of" correct. However, some OpenAPIv2 tools consider it an invalid openAPIv2 spec. For example, the https://github.com/OpenAPITools/openapi-generator for generating client code from OpenAPIv2 spec. If it processes spec that contains ref object with siblings, then this openapi-generator considers this spec as invalid. This limitation has been discussed in the OpenAPI Specification project (OAI/OpenAPI-Specification#556) and it seems that it has been allowed to add siblings to the ref object (in contrary with the JSON standard), but it applies only for OpenAPI v3.1 and only in some cases (OAI/OpenAPI-Specification#556 (comment)). It does not apply for the OpenAPI v2 at all. Current state of protoc-gen-openapiv2protoc-gen-openapiv2 currently generates reference objects with siblings. In #2904 was removed the protection of not adding siblings to the $ref object and in #2906 is even mentioned that in OpenAPI v2 it's ok to have sibling fields of the $ref field (which depends on how you define ok). The reason why the original issue #1937 does not suffer from this invalid Reference Object issue is that in #2553 the reference object was replaced with a full object definition. IMHO this is wrong because it's duplicating the object definition (there could have been some reason for it which I don't see) but that's a different topic. SolutionIMHO it comes down to a decision whether it's ok to keep it as it is. The standards discourage from it and it makes it incompatible with some other OpenAPIv2 tools. On the other hand, it's not explicitly forbidden. There's a workaround by using I'd prefer to follow the standards either by using the @johanbrandhorst what do you think? Is there someone who could help with this? |
Thanks for the great analysis. A couple of points:
CC @gostajonasson. |
Thanks for the quick response! Re 1. The #2553 effectively creates a new object (it's no longer a reference to the resource) and that seems to me as a worse duplication. Client using the OpenAPI has no guarantee that the object in the request body is the same object. There could be some other fields missing or some other fields added (which wouldn't make sense but it's possible when it's a different object). Re 2.
If we add a different valid schema property (e.g. title) then the result is the same / there will be the same warning: The https://github.com/OpenAPITools/openapi-generator (tested with latest version 6.2.1) considers even the
As the error message mentions, it is possible to disable spec validation when using this tool but I wanted to use this option only as a last resort because it's not safe. So other OpenAPIv2 tools treat this issue differently which doesn't help a lot. It would be nice if those spec validators would consider the ref siblings only a warning - maybe those tools should be the ones that should be fixed? Re 3. Another thoughtBesides all these points, I'd like to ask, if it actually makes sense in this exact case to add the "parameters": [
{
"name": "foo",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1Foo",
"required": [
"foo"
]
}
}
], Only the body request parameter "foo" itself is required as defined in protobuf (reflected in OpenAPI by "schema": {
"$ref": "#/definitions/v1Foo",
"required": [
"foo"
] Am I correct? If so, then it doesn't make sense. The Foo object has no property called There are other examples in the a_bit_of_everything that seem suspicious to me: "nested": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/ABitOfEverythingNested"
}
} Why is it necessary to redefine type of a referred object? This information is already included in the object definition: "definitions": {
"ABitOfEverythingNested": {
"type": "object",
"example": {
"ok": "TRUE"
},
"properties": { "enumValueAnnotation": {
"$ref": "#/definitions/examplepbNumericEnum",
"description": "Numeric enum description.",
"title": "Numeric enum title"
} The "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"
} What do you think? PS: @johanbrandhorst thank you for all your help! I don't have a strong knowledge of OpenAPI so please correct me if I don't understand something correctly. |
I don't agree with this interpretation of the AIP. It doesn't say what the behavior should be when the For point 2, thank you for supplying the error from the generator. It's still not clear to me whether it's a problem specifically with
For your other questions:
Great questions, hope that makes sense. |
Your understanding is correct, even if the |
🐛 Bug Report
This is almost exactly the same error as in #1937:
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
andfoo.proto
, if you manually provide the googleapis.Here's the whole Buf setup:
buf.gen.yaml
buf.work.yaml
proto/buf.yaml
proto/buf.lock
Is generated by command:
example content:
proto/v1/foo.proto
Finally, generate openapiv2 via buf command:
(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
Actual Behavior
gen/v1/foo.swagger.json
Your Environment
buf version: 1.10.0
protoc-gen-openapiv2 version: v2.14.0
go version: go1.19.1 darwin/amd64
The text was updated successfully, but these errors were encountered: