connectrpc / connect-es

The TypeScript implementation of Connect: Protobuf RPC that works.
https://connectrpc.com/
Apache License 2.0
1.29k stars 73 forks source link

Swagger/OpenAPI definitions #271

Open george-oakling opened 1 year ago

george-oakling commented 1 year ago

We are quite happily using grpc-gateway, which generates us swagger, which we use for generating TS. Today I found this project and I am amazed! This is a true gamechanger for us, as we would throw away three or four components and make our code pipeline a lot easier :) so in the next few months, we are going to replace our solution with connect.build.

But, using GRPC gateway with OpenAPI definitions has one advantage. We can show structure of our API to 3rd parties with no work at all :) just publishing the Swagger file.

Is it possible to have such swagger file being created? I see that the connect.build doesnt take care of OpenAPI definitions in proto files.

saquibmian commented 1 year ago

Alternatively/additionally, if we could bundle Buf Studio in the generated service, that would be a pretty sweet way to explore the API. Similar to the graphQL playground.

timostamm commented 1 year ago

I'm glad to hear that it works for you, George. Going from one schema definition (protobuf) to a second schema definition (OpenAPI) involves quite a bit of indirection, and some nice features from protobuf like oneofs cannot be described well in OpenAPI (see https://github.com/google/grr/issues/822).

We're a bit hesitant to focus on this feature because of that. We think that protobuf is actually well suited to be published and shared with 3rd parties though! If you run a Connect server, it can be accessed by any gRPC client implementation too, not just Connect clients. That said, I agree that ApenAPI would open up more integration possibilities - happy to keep this open for possible future enhancement!

FPurchess commented 1 year ago

Hi @saquibmian, we have the same challenge of providing an OpenAPI spec to a third party. We love https://github.com/swaggo/swag but unfortunately it doesn't handle one-of's well enough as pointed out by @timostamm. However, If you don't mind, feel free to give it a shot.

Nonetheless, it would be awesome if connect could create at least any kind of human readable API documentation for the HTTP/JSON interface. @timostamm can you give any advice on approaching such a challenge?

FPurchess commented 1 year ago

btw, OAS 3.0 seems to support oneOf / anyOf: https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/

timostamm commented 1 year ago

@FPurchess, are you familiar with protobuf plugins? If not, our docs give an introduction here. A protobuf plugin is definitely the way to go here.

We publish a package that makes it pretty easy to write your own plugin: @bufbuild/protoplugin You can see how it could be used to generate an OpenAPI spec in this gist. I'm happy to answer any questions you might have if you want to give it a go!

(Please note that we are currently making some breaking changes to the package, see https://github.com/bufbuild/protobuf-es/pull/247, https://github.com/bufbuild/protobuf-es/pull/228 and https://github.com/bufbuild/protobuf-es/pull/244)

fubhy commented 1 year ago

We currently use envoy proxy's grpc-json-transcoder filter to achieve this. That works for our setup but comes at a cost of deployment complexity. The transcoder filter requires a service descriptor to properly route requests and properly (de-)serializeback the request and response.

In our case, we have a shared API that is used both interally (service<->service), within our app (service<->web) and, in some cases, also by third parties for whatever they do with it.

Internally and for our own app, we obviously use generated API clients both on our service and in the browser app (connect-web in the future!). Whenever clients reach out and ask for API access, we first point them at the same option of using one of our published API clients for the language of their choice.

That doesn't always work though because sometimes either we don't have a client for their language or, more commonly, they want to simply drop a JSON / REST API endpoint into some kind of browser-based tool, for instance a biz-dev analytics / data-viz tool or similiar.

We even had one client ask about this to be able to drop data from the API directly into a Google Spreadsheet.

The point is that there are indeed very valid use-cases for generating an OpenAPI document and using something like grpc-json-transcoder, grpc-gateway, etc. to expose a grpc service explicitly (using google.api.http).

The proxy sidecar solution works, but it's inconvenient. And I can see the value of having that solved natively on the service-level to reduce the complexity of that setup.

TL;DR: I'd love for connect-go, connect-node, etc. to not only support grpc-web and connect but also straight-up JSON requests based on google.api.http options in the grpc service definition.

edaniels commented 1 year ago

https://github.com/viamrobotics/goutils/tree/main/rpc is kind of similar to what connect is doing, from the server perspective. It currently uses grpc-gateway to serve the google.api.http option annotated services