Frequently Asked Questions
Is this ready for production?
Buf has been using Connect-Query in production for some time. Also, there is 100% mandatory test coverage in this project which covers quite a lot of edge cases. That said, this package is given a v0.x
semver to designate that it's a new project, and we want to make sure the API is exactly what our users want before we call it "production ready". That also means that some parts of the API may change before v1.0
is reached.
What is Connect-Query's relationship to Connect-Web and Protobuf-ES?
Here is a high-level overview of how Connect-Query fits in with Connect-Web and Protobuf-ES:
Expand to see a detailed dependency graph
Your Protobuf files serve as the primary input to the code generators protoc-gen-connect-query
and protoc-gen-es
. Both of these code generators also rely on primitives provided by Protobuf-ES. The Buf CLI produces the generated output. The final generated code uses Transport
from Connect-Web and generates a final Connect-Query API.
What is Transport
?
Transport
is a regular JavaScript object with two methods, unary
and serverStream
. See the definition in the Connect-Web codebase here. Transport
defines the mechanism by which the browser can call a gRPC-web or Connect backend. Read more about Transport on the connect docs.
What if I already use Connect-Web?
You can use Connect-Web and Connect-Query together if you like!
What if I use gRPC-web?
Connect-Query also supports gRPC-web! All you need to do is make sure you call createGrpcWebTransport
instead of createConnectTransport
.
That said, we encourage you to check out the Connect protocol, a simple, POST-only protocol that works over HTTP/1.1 or HTTP/2. It supports server-streaming methods just like gRPC-Web, but is easy to debug in the network inspector.
Do I have to use a code generator?
No. The code generator just calls createQueryService
with the arguments already added, but you are free to do that yourself if you wish.
What if I have a custom Transport
?
If the Transport
attached to React Context via the TransportProvider
isn't working for you, then you can override transport at every level. For example, you can pass a custom transport directly to the lowest-level API like UnaryHooks.useQuery
, but you can also pass it to createQueryHooks
or even as high as createQueryService
. It's an optional argument for all of those cases and if you choose to omit the transport
property, the Transport
provided by TransportProvider
will be used (only where necessary).
Does this only work with React?
You can use Connect-Query with any TanStack variant (React, Solid, Svelte, Vue). However, since the hooks APIs like UnaryHooks.useQuery
and UnaryHooks.useMutation
automatically infer Transport
from React Context, these APIs will only work with React, as of now. There is nothing else React specific in the Connect-Query codebase. As we expand the scope of the project, we do hope to support all APIs on all TanStack Query variants.
Connect-Query API | React | Solid | Svelte | Vue |
---|---|---|---|---|
createQueryService | ✔️ | ✔️ | ✔️ | ✔️ |
createQueryHooks | ✔️ | ✔️ | ✔️ | ✔️ |
isSupportedMethod | ✔️ | ✔️ | ✔️ | ✔️ |
disableQuery | ✔️ | ✔️ | ✔️ | ✔️ |
unaryHooks | ✔️ | ✔️ | ✔️ | ✔️ |
createData | ✔️ | ✔️ | ✔️ | ✔️ |
createUseQueryOptions | ✔️ | ✔️ | ✔️ | ✔️ |
getPartialQueryKey | ✔️ | ✔️ | ✔️ | ✔️ |
getQueryKey | ✔️ | ✔️ | ✔️ | ✔️ |
methodInfo | ✔️ | ✔️ | ✔️ | ✔️ |
setQueryData | ✔️ | ✔️ | ✔️ | ✔️ |
setQueriesData | ✔️ | ✔️ | ✔️ | ✔️ |
useInfiniteQuery | ✔️ | ❌ | ❌ | ❌ |
useMutation | ✔️ | ❌ | ❌ | ❌ |
useQuery | ✔️ | ❌ | ❌ | ❌ |
useQuery | ✔️ | ❌ | ❌ | ❌ |
useTransport | ✔️ | ❌ | ❌ | ❌ |
TransportProvider | ✔️ | ❌ | ❌ | ❌ |
Tip: If you're a TanStack Query user that uses something other than React, we'd love to hear from you. Please reach out to us on the Buf Slack.
SolidJS Example
Say, for example, you're using Solid together with TanStack Query's useQuery
API. In this case you can use UnaryHooks.createUseQueryOptions
instead of UnaryHooks.useQuery
. The only difference is that createUseQueryOptions
requires you to pass in a Transport
because it is not a hook and hooks are where transport is automatically inferred.
Here's an example using SolidJS:
import { createQuery } from "@tanstack/solid-query";
import { getTodos } from "./example-ElizaService_connectquery";
function Component() {
const options = example.createUseQueryOptions(
{ name: 'My First Todo' },
{ transport }
);
const query = createQuery({
...options,
queryKey: () => options.queryKey
});
return <div>{whatever}</div>
}