Skip to content

Commit

Permalink
Add FAQs (#172)
Browse files Browse the repository at this point in the history
Signed-off-by: Carol Gunby <[email protected]>
Signed-off-by: Steve Ayers <[email protected]>
  • Loading branch information
rakuista authored and smaye81 committed Sep 30, 2024
1 parent 2dd728c commit b48ace1
Showing 1 changed file with 116 additions and 13 deletions.
129 changes: 116 additions & 13 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,41 @@ title: FAQs
sidebar_position: 1000
---

## General

### How should I refer to Connect in a blog post or social media?

**Connect** is the name of the project. If that's ambiguous in your context or
search ranking/uniqueness is important, please use **Connect RPC**.

### How do I get the OpenAPI spec for the Connect APIs?

Connect RPCs are defined using Protobuf, which serves as the specification and
documentation. OpenAPI is meant for REST/HTTP endpoints and doesn't apply to RPC
systems like Connect.

## The Connect protocol

### Where can I find Connect implementations?

All implementations are listed at the main [ConnectRPC repository][main-repo].
All implementations are listed at the main [Connect RPC repository][main-repo].

### Is there a way to generate REST paths with Connect?

The path is simply the fully qualified name of the service. There is no built-in option to
modify this path, because it would break compatibility with gRPC and gRPC-Web.

If you want more control over the path, one option would be to use
[gRPC Transcoding](https://github.com/googleapis/googleapis/blob/738ff24cb9c00be062dc200c10426df7b13d1e65/google/api/http.proto#L44),
which allows you to specify REST paths. You could use
[vanguard-go](https://github.com/connectrpc/vanguard-go?tab=readme-ov-file#why-vanguard) or the
[gRPC-Gateway](https://github.com/grpc-ecosystem/grpc-gateway#readme) to serve it.

### Can Connect use HTTP/3?

Yes, although not all Connect implementations have HTTP/3 support. For example, you can
implement it for Connect Go by using the
[quic-go package](https://pkg.go.dev/github.com/quic-go/quic-go/http3) for the server and client.

### Why special-case unary RPCs?

Expand Down Expand Up @@ -49,6 +79,12 @@ require end-to-end HTTP/2, which NGINX doesn't support. Rather than NGINX, we
recommend using Envoy, Apache, or TCP-level load balancers like HAProxy, all of
which support the full Connect protocol.

### Do half duplex streams have a unary and streaming component?

No. Half duplex, server streaming and client streaming, are both defined by the streaming
RPC behaviour. Messages will be encoded in the connect streaming wire semantics as an
enveloped message for both the request and response.

### Why not use HTTP status codes?

Every taxonomy of errors is flawed, but at least HTTP status codes are
Expand All @@ -75,6 +111,14 @@ In the end, we prioritized gRPC and gRPC-Web compatibility over Twirp support.
We hope that Connect's unary protocol captures most of Twirp's magic while
still allowing your code to interoperate with the larger gRPC ecosystem.

### Does Connect RPC support Envoy?

Yes, it offers Envoy support in several ways:

- If you use gRPC and Connect-Go, there is built-in gRPC support
- Connect-gRPC has an [Envoy filter](https://github.com/connectrpc/envoy-demo)
- Connect-Go supports gRPC health checking via https://github.com/connectrpc/grpchealth-go

## Serialization & compression

### Why are numbers serialized as strings in JSON?
Expand Down Expand Up @@ -104,7 +148,7 @@ underlying implementation allows us to do so.
### Why use generics?

Generic code is inherently more complex than non-generic code. Still, introducing
generics to `connect-go` eliminated two significant sources of complexity:
generics to Connect-Go eliminated two significant sources of complexity:

- Generics let us generate less code, especially for streaming RPCs &mdash; if
you're willing to write out some long URLs, it's now just as easy to use
Expand All @@ -116,7 +160,7 @@ generics to `connect-go` eliminated two significant sources of complexity:
This makes data flow obvious and avoids any confusion about inbound and
outbound metadata.

On balance, we find `connect-go` simpler with generics.
On balance, we find Connect-Go simpler with generics.

### Why generate Connect-specific packages?

Expand All @@ -136,12 +180,12 @@ This serves a few purposes:
when generating code locally, but it's critical to making [generated SDKs] and
[remote plugins] work.

### Can connect-go clients be used in browser applications with WASM?
### Can Connect-Go clients be used in browser applications with WASM?

It's technically possible, but please be aware that the WASM in Go is quite new,
and the architecture has some fundamental limitations that may be surprising.
We encourage you to give it a try and report any issues you find to Go or
connect-go to help bring WASM in Go forward.
Connect-Go to help bring WASM in Go forward.

### Why am I seeing a "stream error: stream ID 5; INTERNAL_ERROR; received from peer" error message after X seconds? {#stream-error}

Expand All @@ -153,7 +197,7 @@ clients can see the above error message. The other timeout fields won't cause
this error, and we
encourage you to set `ReadHeaderTimeout` in particular.

### How do I close a client response stream in connect-go?
### How do I close a client response stream in Connect-Go?

On reading the response, a client can call `CloseResponse` on bidirectional
streams or `Close` on server streams to gracefully close the connection.
Expand All @@ -163,12 +207,62 @@ will return the wire error.
Alternatively, if you wish to cancel the operation and immediately stop
the client stream, see [below](#cancel-stream) to cancel the operation.

### How do I cancel a client response stream in connect-go?
### How do I cancel a client response stream in Connect-Go?

To cancel and abort a stream, call the cancel function of the underlying
context associated with the stream. This context is provided on stream
creation. On cancel, the stream is aborted and any resources are released along with it.

### My project is in Go using Buf and the BSR, and now we need to generate JavaScript stubs. How should this project be structured?

If your project implements a service, a common approach is to keep the Protobuf files in the same repository as the
server implementation, and automatically push the schema to the BSR. Other repositories can then take full advantage of
generated SDKs for clients, and don't need to maintain Protobuf plugins or even the Buf CLI.

For a simple example, you could take a look at the [examples-go](https://github.com/connectrpc/examples-go) repository,
which defines the Eliza service (a simple chat bot) and implements a server. The server is deployed to
https://demo.connectrpc.com/, and the schema in the `proto` directory is pushed to
[buf.build/connectrpc/eliza](https://buf.build/connectrpc/eliza) on the BSR. It also includes a JavaScript client app
hosted as a demo on the [home page](https://connectrpc.com) (you can type some text to chat with the Go server). The
source for the demo is public as well, so you can
[look at the client](https://github.com/connectrpc/connectrpc.com/blob/main/src/components/eliza-demo/index.tsx).
The interesting bit is that we simply import from a generated SDK on the client side:

```go
import { ElizaService } from "@buf/connectrpc_eliza.connectrpc_es/connectrpc/eliza/v1/eliza_connect";
```

### Does Connect-Go provide the equivalent of gRPC's `WithBlock` option when connecting to servers?

No, because under the hood Connect-Go is just using an `*http.Client`, but we are evaluating potentially
adding similar functionality to Connect-Go. In the meantime, you can take a look at [github.com/bufbuild/httplb].
It's an `*http.Client` that's not specific to Connect, but solves a lot of the gotchas with using the stdlib
client/transport for RPC, especially if you're using k8s. Keep in mind that it's still in Alpha so the APIs are
unstable, but it's important, so we're continuing to work on it.

### Can the Connect protocol be disabled on the server in Connect-Go?

It's currently not a supported option. As a workaround for now, you can inspect the content type
to classify the request as a grpc/grpcWeb request and return a `415 Unsupported Media Type` status
otherwise. Here is an example in HTTP middleware:

```
func grpcOnlyMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
w.WriteHeader(http.StatusUnsupportedMediaType)
return
}
next.ServeHTTP(w, r)
})
}
```

### How do I customize serialization errors returned by the Connect server?

You can customize the error message by providing a different `Codec`. Code
and details can't be customized.

## TypeScript and JavaScript

### Why do I need a proxy to call gRPC backends?
Expand All @@ -182,7 +276,7 @@ don't support trailers, no code running in a browser can speak the gRPC protocol
To work around this, the gRPC team introduced the gRPC-Web protocol, which
encodes trailers at the end of the response body.

Some gRPC servers (including those built with `connect-go`) support the
Some gRPC servers (including those built with Connect-Go) support the
gRPC-Web protocol natively, so browsers can communicate directly with your
backend. Most of Google's gRPC implementations don't support gRPC-Web, so you
must run a proxy like Envoy to translate to and from the standard gRPC
Expand Down Expand Up @@ -226,20 +320,24 @@ for a detailed explanation and an example.

## Deployment

### How do I handle Authorization Bearer headers through middleware/interceptors?

See https://github.com/connectrpc/authn-go.

### How do I use an interceptor to configure CORS?

Interceptors can't be used to configure CORS. CORS is a security feature of the
browsers and involves `OPTIONS` requests. `OPTIONS` requests can't be matched as RPC
requests, and so interceptors can't be used to configure CORS. It's purely an HTTP
concern. Both [connect-go][cors-go] and [connect-es][cors-es] have
concern. Both [Connect-Go][cors-go] and [connect-es][cors-es] have
docs that show how to configure CORS for their respective HTTP libraries.

### How does vanguard-go integrate with Connect interceptors?

A `connect-go` handler wrapped with [Vanguard](https://github.com/connectrpc/vanguard-go)
can use connect-go interceptors like
any other connect-go handler, whether the incoming request is REST or one of the
supported protocols. connect-go interceptors cannot be applied to gRPC handlers or
A Connect-Go handler wrapped with [Vanguard](https://github.com/connectrpc/vanguard-go)
can use Connect-Go interceptors like
any other Connect-Go handler, whether the incoming request is REST or one of the
supported protocols. Connect-Go interceptors cannot be applied to gRPC handlers or
proxy handlers. Use gRPC interceptors or net/http middleware instead.

### Missing trailers with Ambassador
Expand Down Expand Up @@ -268,6 +366,11 @@ Route HTTP GET requests and anything with the `application/proto`, `application/
`application/connect+proto`, or `application/connect+json` Content-Types to the
HTTP2 target group. Route anything else to the gRPC target group.

### How do I send metrics to Prometheus in Connect-Go?

Connect has support package for OpenTelemetry: https://pkg.go.dev/connectrpc.com/otelconnect.
Prometheus can be configured as an exporter.

[cors-es]: https://connectrpc.com/docs/node/server-plugins/#cors
[cors-go]: https://connectrpc.com/docs/go/deployment#cors
[generated SDKs]: https://buf.build/docs/bsr/generated-sdks/overview/
Expand Down

0 comments on commit b48ace1

Please sign in to comment.