Skip to content
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

Merging two .proto files with different packages using protoc-gen-swagger throws error #837

Open
bsakweson opened this issue Jan 6, 2019 · 11 comments

Comments

@bsakweson
Copy link

bsakweson commented Jan 6, 2019

I ran into an issue similar to 746,.

I have a setup with multiple micro services each defined in their own .proto file. Code generation works well until I tried to combine my openAPI documentation using protoc-gen-swagger from grpc-gateway.

Using this command protoc --proto_path=api/v1 --proto_path=$GOPATH/src --proto_path=third_party --swagger_out=logtostderr=true,allow_merge=true:third_party/OpenAPI a/a.proto b/b.proto to generate a merged apidocs.swagger.json file containing all services defined in a and b respectively so that I can serve it as a single page throws this error --swagger_out: inconsistent package names: a b . Notice that a and b are all in different packages a and b.

service a:

syntax = "proto3";

package com.somecompany.a;

option go_package = "a";

import "google/api/annotations.proto";

// A is a service for handling Foo stuff.
service A {
  // List all Foos
  //
  // Returns a (possibly paginated) list of all foo resources on success.
  rpc ListFoos (ListFoosRequest) returns (ListFoosResponse) {
    option (google.api.http) = { get: "/v1/foos" };
  }
}

// The ListFoos request message.
message ListFoosRequest {}

// The ListFoos response message.
message ListFoosResponse {}

service b:

syntax = "proto3";

package com.somecompany.b;

option go_package = "b";
import "google/api/annotations.proto";

// B is a service for handling Bar stuff.
service B {
  // List all Bars
  //
  // Returns a (possibly paginated) list of all bar resources on success.
  rpc ListBars (ListBarsRequest) returns (ListBarsResponse) {
    option (google.api.http) = { get: "/v1/bars" };
  }
}

// The ListBars request message.
message ListBarsRequest {}

// The ListBars response message.
message ListBarsResponse {}

Am I using this incorrectly? I would think that my use case is plausible since having each service in its own package helps maintained separation of concerns and keep service module smaller.

@johanbrandhorst
Copy link
Collaborator

johanbrandhorst commented Jan 6, 2019

Haha I already answered in #746, but to clarify, it is currently working as intended, that is not to say that we couldn't look into making this work.

I would say that it's not uncommon when existing a set of services to specify another, superset service and use that with the gateway as a simple proxy to the others.

@bsakweson
Copy link
Author

Would you by any chance know of any hack I can use for now to get those swagger files concatenated, if so would mind sharing?

@johanbrandhorst
Copy link
Collaborator

I think you'd have to write a post processing tool to read both and merge the fields. There probably exists tools to do this.

@birdayz
Copy link
Contributor

birdayz commented Jan 30, 2019

@bsakweson https://github.com/go-swagger/go-swagger can merge swagger files. we're using this to create one unified swagger definition.

@daicoden
Copy link

daicoden commented Jun 7, 2021

I wanted to generate the API into a single swagger file with services spread out throughout the codebase (which I believe is the same issue referenced here).

I changed the proto argument to take a label_list, and updated a few locations to handle it.

CFHT/grpc-gateway-api-test@c05b2e2

and I now I can define a singular rule in the project that references all of the services I want included in the API documentation.

protoc_gen_openapiv2(
    name = "openapi",
    proto = [
        ":api_proto",
        ":service_proto",
        "//common/domain:point_service_proto", # note different package here!!! this was the problem. woot!
    ],
    single_output = True,
)

Is this something you'd be interested in a PR for if I cleaned it up? Is there something I'm missing that makes this a bad idea?

@johanbrandhorst
Copy link
Collaborator

Would this be a breaking change from today? I'm not familiar enough with our rule to say. Maybe @achew22 can weigh in.

@daicoden
Copy link

daicoden commented Jun 9, 2021

We could add a new option, protos, which takes a list. The macro would require either proto or protos specified, then I believe it would be backwards compatible.

@llsj14
Copy link

llsj14 commented Mar 28, 2022

Hello, I have similar issue to generate single swagger file from multiple proto files.

I found out that there was an effort to generate single swagger output from multiple proto files in protoc-gen-swagger. (#658)
this document said protoc-gen-swagger has been renamed protoc-gen-openapiv2.

Until now, it is the best way to generate single swagger file is to merge multiple swagger files using go-swagger tool? (thanks to @birdayz)
So, there is no similar option or functionality to generate one single swagger output from multiple proto files like protoc-gen-swagger in protoc-gen-openapiv2?

@johanbrandhorst
Copy link
Collaborator

There definitely is: https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_openapi_output/#merging-output

@llsj14
Copy link

llsj14 commented Mar 28, 2022

oh wow, thanks for the info. 👍 I was so confused with lots of issues, but finally I could generate swagger file that I want, thanks for your comment.

@johanbrandhorst
Copy link
Collaborator

Nice, happy to hear it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants