-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
fix(openapi): generate correct schema definition for google.protobuf.Any #2180
Conversation
if core.Ref != "" { | ||
refs[fd.GetTypeName()] = struct{}{} | ||
} | ||
|
||
if fd.GetTypeName() == ".google.protobuf.Empty" { | ||
props = &openapiSchemaObjectProperties{} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be tidied up now, and props
for .google.protobuf.Empty
be defined on the wktSchemas
map. Can address this later (I need to log off for a few hours)
@@ -157,7 +157,10 @@ type schemaCore struct { | |||
Ref string `json:"$ref,omitempty"` | |||
Example json.RawMessage `json:"example,omitempty"` | |||
|
|||
Items *openapiItemsObject `json:"items,omitempty"` | |||
// Properties can be recursively defined | |||
Properties *openapiSchemaObjectProperties `json:"properties,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this from the openapiSchemaObject
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just been familiarising myself with the changes I made before adding tests and I'm wondering whether or not this field should be moved back to openapiSchemaObject
, or whether the change I've made is OK.
If we keep this change, we can also remove the workarounds on lines 1041 and 1108.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused, could you elaborate on the reason for moving it? Does it make more sense for the openapiv2 output we're trying to get?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it makes the code easier to handle the edge-cases for the .google.protobuf.Empty
type, at the minute there are if statements dotted around on lines 1041 and 1108 which could be removed if this change is kept.
However, as a more general point, I don't really understand why schemaCore
and openapiSchemaObject
are different types. The only usage of schemaCore
in a type is in openapiSchemaObject
and openapiItemsObject
. As far as the JSON Schema spec goes, "items"
is another schema (I'm not certain if this holds true for OpenAPI - I know there are a few differences).
If we wanted to keep things really simple, I'd do away with schemaCore
completely, move the properties into openapiSchemaObject
and refactor usages as necessary.
So I've just pushed another commit with a different approach which seems to do what it's supposed to. However now we have a problem that the generated go code from swagger-codegen doesn't actually match what it's meant to be. Will comment inline on what I mean |
Codecov Report
@@ Coverage Diff @@
## master #2180 +/- ##
==========================================
+ Coverage 59.16% 59.28% +0.12%
==========================================
Files 35 35
Lines 4484 4500 +16
==========================================
+ Hits 2653 2668 +15
Misses 1544 1544
- Partials 287 288 +1
Continue to review full report at Codecov.
|
@@ -10,6 +10,5 @@ | |||
package generateunboundmethods | |||
|
|||
type ProtobufAny struct { | |||
TypeUrl string `json:"typeUrl,omitempty"` | |||
Value string `json:"value,omitempty"` | |||
Type_ string `json:"@type,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swagger-codegen
now generates go code which I wouldn't expect to work. Really I'd expect this type to not be generated, and any usages of ProtobufAny
actually be of type interface{}
, and say it's up to the caller to provide a value which marshals to a JSON object which is valid under the rules set out by the protojson package.
I guess this would be a swagger-codegen problem, and one which most likely exists across most programming languages. Not sure how to approach this.
FYI, this isn't working yet. Just tried to use my locally built version on my project and there's an issue where swagger-ui won't allow additional properties to the |
Ok, this seems to be working for now, but going to spend a couple more days finishing my tasks with work using my fork and if all goes well I'll add some tests and hopefully have this mergeable by the end of next week. |
Sounds great, thank you! |
Apologies I've not had chance to pick this up. I was doing this for work and my personal life got in the way. I'm on holiday now but will be able to finish this hopefully next week. |
No pressure buddy, I'm here to review whenever you need it :). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just opened this back up, rebased on top of the latest master
and got familiar with my changes before adding tests.
I've added a comment to types.go
, I'd like a response from somebody with more experience in this project.
I'm aiming to add some tests tomorrow.
@@ -157,7 +157,10 @@ type schemaCore struct { | |||
Ref string `json:"$ref,omitempty"` | |||
Example json.RawMessage `json:"example,omitempty"` | |||
|
|||
Items *openapiItemsObject `json:"items,omitempty"` | |||
// Properties can be recursively defined | |||
Properties *openapiSchemaObjectProperties `json:"properties,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just been familiarising myself with the changes I made before adding tests and I'm wondering whether or not this field should be moved back to openapiSchemaObject
, or whether the change I've made is OK.
If we keep this change, we can also remove the workarounds on lines 1041 and 1108.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, but I'd like some more background on some of the changes before we merge.
".google.protobuf.Empty": { | ||
Properties: &openapiSchemaObjectProperties{}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the consequence of this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I did this to remove the random if statements on lines 1041 and 1108, but forgot to actually remove them. However still happy to discuss what to do around moving the Properties
field.
// if wfkSchema is a reference to another known type, add it to refs to be processed later | ||
if core.Ref != "" { | ||
refs[fd.GetTypeName()] = struct{}{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this change, could you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember exactly, however I believe this was the previous behaviour:
rpcStatus
(which references protobufAny
) is hardcoded to always output in the definitions
object, and rpcStatus.details
is an array of "$ref": "#/definitions/protobufAny"
.
If you define a type in your API with a google.protobuf.Any
field, the generated schema outputted the schema as an explicit schema under that properties object, and not as a $ref
. This meant if your schema referenced Any
multiple times, your schema would define the schema for Any
in every usage, growing your schema.
Because our wktSchemas
maps now includes .google.protobuf.Any
as a known-type with the ref field populated, any references to Any
in a custom type will be declared using said $ref
. However we need to make sure that the type is still outputted to definitions
, so we add it to the refs
map so that it is added during the call to addCustomRefs
.
@@ -157,7 +157,10 @@ type schemaCore struct { | |||
Ref string `json:"$ref,omitempty"` | |||
Example json.RawMessage `json:"example,omitempty"` | |||
|
|||
Items *openapiItemsObject `json:"items,omitempty"` | |||
// Properties can be recursively defined | |||
Properties *openapiSchemaObjectProperties `json:"properties,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused, could you elaborate on the reason for moving it? Does it make more sense for the openapiv2 output we're trying to get?
I've found a better way to fix this and added tests, going to close this and reopen a new PR to make reviewing easier |
References to other Issues or PRs
Fixes #2177, but still needs some tests.
Have you read the Contributing Guidelines?
Brief description of what is fixed or changed
See comments in #2177, but this essentially adds a new entry to the well-known types which is a ref to the type which will be generated by
customRefs
. We then do some edge-case handling at the end ofrenderMessageAsDefinition()
when processing theAny
type to make sure the field is@type
and nottypeUrl/type_url
.