-
Notifications
You must be signed in to change notification settings - Fork 17
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
V1 API: Wrapping react-query #224
Conversation
Co-authored-by: Timo Stamm <ts@timostamm.de>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API looks great! Left some questions
@@ -67,30 +67,23 @@ const generateServiceFile = | |||
f.print("}", isTs ? " as const" : "", ";"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need the service here line 49 to 67 can be deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left this for ease of writing tests. Ideally, we'd remove this before we actually merge it, assuming we're happy with the method descriptor.
export { useTransport, TransportProvider } from "./use-transport.js"; | ||
export type { | ||
UseInfiniteQueryOptions, | ||
createUseInfiniteQueryOptions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to export the create*Options
APIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these are needed when used with useQueries({ queries: [ createUseQueryOptions(...) ] })
in order to define parallel queries. I thought perhaps we could define our own useQueries()
but that would mean it would be impossible to mix connect queries with other external queries.
@tannerlinsley It'd be great to get your inputs on the new API. I think you also had feedback regarding what the hooks accept as input for the rpc requests. |
@srikrsna-buf @timostamm Alright, i've updated the readme for a pass at documentation (update to doc page will obviously need to wait). I wanted to gauge a few ideas about release.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just had one suggestion:
I think we should expose functions to call an rpc (unary to begin with) that accept a transport and the request in a type safe way. Then users will never need to interact with connect-web
and more importantly protoc-gen-connect-es
and can directly call rpcs. This is will more or less look like the unary query function.
If we expose this function then we can also un export the create*
functions reducing the API surface significantly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates to the docs!
Krishna's suggestion seems to be worthwhile to me.
@srikrsna-buf hmm, I see what you mean. So instead of having something link: const [result1, result2] = useQueries({
queries: [
createUseQueryOptions(serviceMethod1, input1, options1),
createUseQueryOptions(serviceMethod2, input2, options2)
]
}); We'd just document/encourage the following: const [result1, result2] = useQueries({
queries: [
{ queryKey: createConnectQueryKey(serviceMethod1, input1), queryFn: createConnectQueryFn(serviceMethod1, input1, options1) },
{ queryKey: createConnectQueryKey(serviceMethod2, input2), queryFn: createConnectQueryFn(serviceMethod2, input2, options2) },
]
}); I find that a little more error prone myself (due to potential mismatches between queryKey and queryFn) but it does admittedly reduce the API surface layer. We'd still need another function for infiniteQueries since the key generated for that is actually slightly different than our default key (since pageParam impacts the key). Perhaps we can simplify the exported options a little bit though.The difference between suspense/non-suspense APIs are entirely within the options they take, to make it consistent with other APIs (like useQuery/useSuspenseQuery). Perhaps a function similar to our old API that just returns |
Use the non-suspense versions with suspense hooks works fine, just have to provide any additional options manually.
@srikrsna-buf @timostamm updated docs and API to remove the dedicated |
Created a utility to call a method directly from the descriptor.
Chatted offline, decided to reduce API surface further by removing all the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Maybe @timostamm has an opinion about what the call function should look like but we can revisit that part, so stamping for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice, let's get this merged!
But the PR title "Experimental API suggestion" is not descriptive. The title needs to summarize what this does.
Also:
-
When this is released, we need to explain crystal clear what is changing, why, and what users need to do. IMO it's best to do that right in the PR description, but I'm fine doing it just in the release notes if you prefer.
-
Does it make sense to rename the package
@connectrpc/connect-query
to@connectrpc/connect-react-query
in this PR? Splitting it out into a separate change would make it quite a bite easier to follow what's going on.
@timostamm i will definitely update the pr description to layout all the changes and why. Plus some migration examples. As for your 2nd point, I was originally thinking that this plug-in was no longer react specific so it could be used for any version of connect-query but since that doesn't exist yet, perhaps that's optimizing for a later case that's not important. I would be down with renaming the plug-in. |
My one argument for not renaming the plugin, is the ending of the file get's pretty long, so it'll generate things like: |
I can't follow. The plugin name doesn't change, from what I can see. |
@timostamm oh, i definitely misread, sorry. Yeah I can see why moving the rename to a different PR would make sense. I'll update. |
@timostamm alright, removed package rename (which we'll discuss separately offline). |
## What's Changed * V1 API: Wrapping react-query by @paul-sachs in #224 ## V1 Release 🚀 Introducing a whole new API for connect-query. This API ties itself more tightly with the fantastic `@tanstack/react-query` in order to improve developer experience and reduce bundle size. At the core of this change is the new `MethodUnaryDescriptor` type, which is essentially just a self contained description of a service method. The new code generator just outputs one of these per method and those are passed to the hooks/methods. This new additional type brings a huge level of flexibility about how we write additional methods, and it's trivial to write your own hooks/methods around these simple types. ### Example usage ```tsx import { useQuery } from "@connectrpc/connect-react-query"; import { say } from "./gen/eliza-ElizaService_connectquery"; ... const { data } = useQuery(say); ``` ### Breaking changes - `use*Query` hooks now return data instead of just options. - Many `create*` methods have been removed. - `protoc-gen-connect-query` now outputs very simple method descriptors instead of a bunch of hooks per method. ### Reasoning There are a number of reasons we've decided to make this major breaking change. 1. The API surface is much smaller, leading to less confusion about how to use each method. 2. Smaller core code size and more modular organization leads to better tree shaking (since each generated method doesn't come along with a generated hook). 3. Package names are now explicit about their dependencies, making it easier to develop other packages based on these packages/generated code. 4. More tightly integrating with `@tanstack/react-query@5` provides better usage of Suspense versions of the API. 5. New generated code is easier to expand and build your own custom hooks for. ### Migration The migration process is easy but manual: #### Before ```tsx import { getUserOrganization } from "@apigen/org/alpha/registry/v1alpha1/organization-OrganizationService_connectquery"; import { useQuery } from "@tanstack/react-query"; ... const getUserOrganizationQuery = useQuery({ ...getUserOrganization.useQuery({ userId: currentUser?.id, organizationId, }), useErrorBoundary: false, enabled: currentUser !== null, }); ``` #### After ```tsx import { getUserOrganization } from "@apigen/org/alpha/registry/v1alpha1/organization-OrganizationService_connectquery"; import { useQuery } from "@connectrpc/connect-react-query"; ... const getUserOrganizationQuery = useQuery(getUserOrganization, { userId: currentUser?.id, organizationId, }, { useErrorBoundary: false, enabled: currentUser !== null } }); ``` ## New Contributors * @chrispine made their first contribution in #243 **Full Changelog**: v0.6.0...v1.0.0
Introducing a whole new API for connect-query. This API ties itself more tightly with the fantastic
@tanstack/react-query
in order to improve developer experience and reduce bundle size.At the core of this change is the new
MethodUnaryDescriptor
type, which is essentially just a self contained description of a service method. The new code generator just outputs one of these per method and those are passed to the hooks/methods. This new additional type brings a huge level of flexibility about how we write additional methods, and it's trivial to write your own hooks/methods around these simple types.Example usage
Breaking changes
use*Query
hooks now return data instead of just options.create*
methods have been removed.protoc-gen-connect-query
now outputs very simple method descriptors instead of a bunch of hooks per method.Reasoning
There are a number of reasons we've decided to make this major breaking change.
@tanstack/react-query@5
provides better usage of Suspense versions of the API.Migration
The migration process is easy but manual:
Before
After
Fixes #220