-
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
Add swagger support #68
Conversation
Amazing! I'm afraid, but it takes a bit long to take a look at this PR since it is large. |
@achew22
There are some comments.
|
I have been on vacation for the past week. I intend to start taking a look at this in my spare time over this week. |
👍 |
@yugui, I have done a bit of cleanup on this PR. Just for reference, once you're happy with it I would like to squash it into a single commit, so don't just hit the merge button 😄. I think your suggestion about using a parameter object is a great one. I looked at the docs and agreed with you when I was writing but I couldn't find a compelling way to do union types in Golang. Do you know what the best way to do a union type is? That seems to me like the only way to do it unfortunately. I have updated the branch with changes to make it reuse the existing protoc-gen-grpc-gateway instead of my clone. Turns out almost all the stuff I wanted was there. |
import ( | ||
"errors" | ||
"fmt" | ||
// Don't use the formatter |
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.
Could you just remove this if you don't need "go/format"?
https://travis-ci.org/gengo/grpc-gateway/builds/97933023 The test is broken because master branch was broken. |
The thing I'm stuck on right now is that you can import arbitrary protos into your api. They don't necessarily have to be included in the file that you're currently compiling. My plan thus far had been to use "#/definitions/{{message.FQMN()}}" for all the definitions. This is great, except when it comes to iterating over all the messages, I get stuck because they may not be in the file. Right now I'm expecting that I will have to create a registry of messages, like you did, then recurse through all the fields creating a set of messages that have been seen. I was planning on using a hashmap from FQMN to the actual message object then in the stage where I generate the definitions I can just emit each entry as a definition. Looking at the go code it solves this by importing 1 layer deep and then using the protoc-go library's output to solve the problem of transitive dependence, but you might have a cool trick up your sleeve so I thought I would ask. |
Now I remember why this was hard! Field [https://godoc.org/github.com/gengo/grpc-gateway/protoc-gen-grpc-gateway/descriptor#Field] has a message attached, but it isn't the message I would expect. It is the message of it's parent. This is, no doubt, useful but not in the context that I need it. Lemme go dig in to see if I can figure out how to add a FieldMessage field to the Field struct. Meta-programming is hard! |
After a bit of playing, I just plumbed the registry through to the generator and now I'm able to resolve these. Thanks for writing that! |
Sorry, I accidentally closed this by pushing your master to github. It's all fixed now. I think this is getting a lot closer. I have created a non-streaming example file which is the a bit of everything with the word streaming removed https://raw.githubusercontent.com/achew22/grpc-gateway/master/examples/examplepb/streamless_everything.swagger.json If you want to see how their API viewer sees it, check out http://petstore.swagger.io/#/ and type that URL in at the top. If you want to see what linter checks it is failing you can go to https://editor.swagger.io and do the same thing. Things that still need to be done:
|
I see. I'm looking forward to seeing it. |
My intent is to turn protoc-gen-swagger into a swagger JSON generating protoc plugin.
Previously I had forked the protoc-gen-grpc-gateway folder because I wasn't sure how many changes I was going to have to make to it. Since there weren't very many changes required. I have patched it to add the fields I required and moved gen-swagger to use gen-grpc.
This also adds an error condition that I hadn't previously considered. If there is a streaming API swagger doesn't currently support it. I handle that now with an error.
Also does a major refactor. This changes the way that Messages are discovered and breaks the generation step down from a monoloithic task into a much easier to test set. Also parses paths and adjusts them so that they match what swagger expects.
Swagger uses the operationId as the "nickname" for the method generated for your service.
The tag is used to define the class name in code generation out of Swagger.
@achew22 |
PTAL |
output := fmt.Sprintf("%s.swagger.json", base) | ||
files = append(files, &plugin.CodeGeneratorResponse_File{ | ||
Name: proto.String(output), | ||
Content: proto.String(string(formatted.Bytes())), |
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.
Use bytes.Buffer.String()
to avoid unnecessary copy.
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.
Thank you
The design looks good to me. |
|
||
// We now have rendered the entire swagger object. Write the bytes out to a | ||
// string so it can be written to disk. | ||
w := bytes.NewBuffer(nil) |
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.
You don't have to allocate the buffer in heap.
var w bytes.Buffer
enc := json.NewEncoder(&w)
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.
Saving memory 👍
Thank you so much for the review. This is my first bout with Golang and I'm happy to have someone reviewing it. I think I have addressed all your concerns and would appreciate if you could take another look at the code. |
LGTM. Thank you for your excellent work! |
…ttransactioninfobyid_api add transactioninfobyid api
Yuki,
I started to create a grpc-gateway swagger client which generates a .swagger.json file for every proto that you load in. This is what I have right now. It is broken into two commits. The first clones protoc-gen-grpc-gateway into protoc-gen-swagger and the 2nd modifies it to emit a really terrible swagger definition.
Right now it has a number of shortcomings.
I was wondering if you could provide some general feedback. This is the first thing of any size I've ever done in go so sorry if it isn't idiomatic. I'm seeking comments on places that you think could be improved but please do the delta from the 2nd commit on or it will be very painful to review. "This looks like it's on the right track" or "try again with this strategy" is ultimately what I would like to get from you.
Thanks so much for creating this project! It is making my life so much less painful.