-
Notifications
You must be signed in to change notification settings - Fork 252
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-openapi] Support Fully Qualified Schema Names and Annotations for File/Document and Method/Operation #324
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). For more information, open the CLA check for this pull request. |
@googlebot I signed it! |
@timburks Could you have a look at the PR when you have time. Thanks! |
@timburks I'm in the process of bringing the functionality of protoc-gen-openapi close to the grpc-gateway-openapiv2 one in terms of customization, but all may changes are based on each other. Do you want everything in one huge PR? Or would you prefer smaller ones? If smaller ones, then this PR is what most of the newer ones will be based off of so I would really appreciate it if the could get reviewed, and if you approve, merged. Thanks! |
@jeffsawatzky Thanks for this work and your explanations. I'll review (and expect to approve) this today; from your note at the top, it all SGTM. Would you mind spelling out what you mean by "bringing the functionality of protoc-gen-openapi close to the grpc-gateway-openapiv2 one in terms of customization"? What specific things are you hoping to add? Just wanting to sync on top-level goals. Thanks! /cc @morphar |
@timburks being able to embed OpenAPI elements into the proto as options so you can define extra things like security on a method within the proto file. I've added examples of this to the tests in this PR. Also, envoy and grpc-gateway return errors using the |
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.
@jeffsawatzky thanks, this looks great. I really like the options annotations and how well they fit into the gnostic data structures.
I'll let this sit overnight (California time) in case @morphar has time to look and comment and if no objections come up, I think we can merge this tomorrow morning (PDT).
option go_package = "./openapiv3;openapi_v3"; | ||
|
||
extend google.protobuf.FileOptions { | ||
Document document = 1042; |
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 (just digesting), this allows an arbitrary OpenAPI document to be attached to a file, presumably a partial document that gets overlaid/merged onto the generated OpenAPI spec.
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.
@timburks Correct. It will do a proto merge on the result Document
and any openapi.v3.document
options it finds while compiling the proto files.
} | ||
|
||
extend google.protobuf.MethodOptions { | ||
Operation operation = 1042; |
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.
Similarly, this merges an Operation into the operation generated for a method. This is a gnostic type (as is Document) - and I notice from your example that you're assigning them with valid structs, which are unintuitive to most OpenAPI users but fit the gnostic protobuf model - and I think that consistency is good. Without looking through your generator code (yet), I guess that makes it easier to merge these with the generated doc since that's working on gnostic protobuf-based structs.
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.
Protocol Buffer options need to be defined using protocol buffers themselves. So you will never get a 1-1 mapping of the options structure with OpenAPI structure as protocol buffers are strictly typed and yaml/json are not. Also, this is similar to how the protoc-gen-openapiv2 generator works from the grpc-gateway project (though they use protocol buffers that are specific to OpenAPI v2/Swagger). I think most developers that will use this will understand this.
Since I need to use protocol buffer messages for the options, I reused the same ones that gnostic was already using to make merging them easier, as you said.
// Merge any `Document` annotations with the current | ||
extDocument := proto.GetExtension(file.Desc.Options(), v3.E_Document) | ||
if extDocument != nil { | ||
proto.Merge(d, extDocument.(*v3.Document)) |
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.
Nice, this seems really clever and elegant. I wonder if there are any other places (besides methods and files) where it would make sense to attach a partial document - maybe messages or fields?
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.
Yeah, I can add the same for Messages=>Schemas and Fields=>Parameters. But didn't want to do too much in case you reject the whole idea. I can do this in a separate PR.
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 that would be great, thanks!
Title: flags.String("title", "", "name of the API"), | ||
Description: flags.String("description", "", "description of the API"), | ||
Naming: flags.String("naming", "json", `naming convention. Use "proto" for passing names directly from the proto files`), | ||
FQSchemaNaming: flags.Bool("fq_schema_naming", false, `schema naming convention. If "true" prefixes the schema name with the proto message package name`), |
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.
Let's spell out what "fq" stands for here in the help string, maybe like this:
If "true", generates fully-qualified schema names by prefixing them with the proto message package name.
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 have a couple more PRs coming. I will update the help string there, if that's ok with you.
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.
Yes, SGTM
// The Go package name. | ||
option go_package = "./openapiv3;openapi_v3"; | ||
|
||
extend google.protobuf.FileOptions { |
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.
The other files in this directory are automatically-generated - that's not a problem, and I think this is a good place to put this file, especially since it refers to types defined inside the package.
Eventually (not necessarily in this PR) I think it would be good to have some documentation here of how these annotations work. google/api/http.proto is a good example of this - though I'm not thinking of anything nearly as elaborate as that, that file seems to be a good example of where to put proto documentation -- in comments in the protos so that it never gets separated.
Sorry, I was away from my computer, I'll have a look at it now :) |
I have no comments to add whatsoever! It looks really good to me 👍 As far as I can tell, all existing things just works, while adding some nice functionality. Really nice @jeffsawatzky 👍 |
so, merge this plz. I really need this feature too. 👍 |
@timburks / @morphar once you merge this PR, can you also take a look at my other PR #327 which is based on this? I have some more functionality that I would like to add for my use case, such as adding an option for a |
It's only @timburks who can add tags and versions. I'm just a contributor :) |
This does a couple things:
formatMessageRef
function as it was basically a duplicate offormatMessageName
, and with the above refactor it wasn't needed anymorefq_schema_naming
Fixes #308
Fixes #309
Fixes #322