grpc-gateway icon indicating copy to clipboard operation
grpc-gateway copied to clipboard

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

Open bsakweson opened this issue 6 years ago • 11 comments

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.

bsakweson avatar Jan 06 '19 06:01 bsakweson

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.

johanbrandhorst avatar Jan 06 '19 08:01 johanbrandhorst

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?

bsakweson avatar Jan 19 '19 19:01 bsakweson

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.

johanbrandhorst avatar Jan 19 '19 23:01 johanbrandhorst

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

birdayz avatar Jan 30 '19 07:01 birdayz

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.

https://github.com/CFHT/grpc-gateway-api-test/commit/c05b2e2af18c5233bb6b9beeee3ed7d602b93bda

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?

daicoden avatar Jun 07 '21 09:06 daicoden

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

johanbrandhorst avatar Jun 09 '21 01:06 johanbrandhorst

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.

daicoden avatar Jun 09 '21 02:06 daicoden

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. (https://github.com/grpc-ecosystem/grpc-gateway/pull/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?

llsj14 avatar Mar 28 '22 13:03 llsj14

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

johanbrandhorst avatar Mar 28 '22 14:03 johanbrandhorst

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.

llsj14 avatar Mar 28 '22 14:03 llsj14

Nice, happy to hear it!

johanbrandhorst avatar Mar 28 '22 14:03 johanbrandhorst