Best practices in naming and defining procedures when they don't fit into standard buckets?

I am loving TRPC and its type safety, but I feel like I'm struggling with the naming of procedures. I'm pretty confused with why I need to fit my procedures into one of the 3 buckets: query, mutation, or subscription. For example, I have items. They can be queried, mutated and subscribed to. And maybe a few more things - items can be generated, created, pulled from a remote source, deleted, renamed, aliased, etc. But let's try to fit this into these prescribed buckets. I felt inclined to define items as a publicProcedure with all 3 verbs. But I have to choose only one, not all three. The api does not support chaining on multiple verbs. If I want to support all 3, I have to differentiate them as separate procedure definitions such as getItems, updateItems, and subscribeToItems... but then, what's the point of query/mutate/subscribe if I am already differentiating them as separate procedure names? Now the client api surface is weird: I wanted the client code to read: client.items.query(), or client.items.mutate(...) I'm fine with it if I can just have client.getItems() or client.updateItems(...) Instead I have redundancy in the naming: client.getItems.query(), client.updateItems.mutate(...) To make things more confusing, some procedures just don't fit into these buckets. I can have procedures which read nothing, write nothing, but perform some action like open a file in vscode. None of the above conventions work in this case. My expectation when using it was simply to have an execute call, and let the author decide their naming conventions. If there is nothing special about a query or mutation, why introduce weird things that mess with the naming conventions and don't work in every case?
Nick
Nick383d ago
Name procedures like you would name the function that does a thing So client.users.giveAccountAccess.mutate() or client.users.list or .getList It’s very much a case of naming is hard (in general) and you should do what feels best at the time
diz6157
diz6157382d ago
right, but my question is, why the need to have "mutate()" or "query()" at the end of the function? (or rather, is there a way to avoid using a category, so that my client is just client.giveAccountAccess() which is nice and predictable?)
Nick
Nick382d ago
This is a tRPC thing for sure Not really a way to avoid it
diz6157
diz6157382d ago
I can have a wrapper that abstracts the client returned from createTRPCProxyClient which removes the extra category, that's all i could come up with
Nick
Nick382d ago
Under the hood it controls things like the HTTP verb to use, so it does matter
diz6157
diz6157382d ago
that's a good point. So I'm assuming query=get, mutation=post
Nick
Nick382d ago
Essentially yes It can change how you frame your semantics too I often write my procedures in terms of resources, so prefer .list.query rather than .getList.query But it’s preference
diz6157
diz6157382d ago
in that case: what if your list can be queried and mutated and subscribed? is there a way to provide all 3 for a single resource? (i'm guessing that in that case "list" is a procedure) so that we could have client.list.query(...), client.list.mutate(...)
Nick
Nick382d ago
I actually don’t think that would be impossible to build Feel free to open a GitHub issue on it, but it’s not a current feature no
diz6157
diz6157382d ago
Sure thing. Thanks for the help Nick!
Sandvich
Sandvich382d ago
Sorry to hijack this thread but this looks like a cool idea. I scaffolded out how that might look to create many procedures and this just looks really nice
const test = router({
greeting: {
query: publicProcedure
.input(z.string())
.query(({ input }) => {
return `Hello ${input}!`;
}),
mutation: publicProcedure
.input(z.object())
.mutation(() => {}),
subscription: publicProcedure.subscription(() => {
// ...
}),
}
});
const test = router({
greeting: {
query: publicProcedure
.input(z.string())
.query(({ input }) => {
return `Hello ${input}!`;
}),
mutation: publicProcedure
.input(z.object())
.mutation(() => {}),
subscription: publicProcedure.subscription(() => {
// ...
}),
}
});
You could argue there's some duplication in key name and method name but I think it's fine
Nick
Nick382d ago
Go ahead and create a GitHub issue! Can’t promise we’ll tackle it soon or at all, but PRs are especially welcome if they prove the concept
diz6157
diz6157382d ago
i'll post one
More Posts
Separating routers into their own modules and merging them causes "any" type in clientHi all, I've separated my router into multiple files, but when merging them I get `any` types for acustom query functionI have a use case where I need a trpc procedure call when a specific key is not present in the localTRPC type checking during build failsEnvironment: node 18.6.0, yarn Whats wrong: Type checking at build time fails. . I think this mightcreateTRPCNext config ctx always returns undefined.Hi Everyone. So I'm trying to use TRPC and Nextjs for auth and post query etc. I have client side cStandalone Next.js 13.3.2 errorHi, since the 13.3.2 update of Next.js, I have the following error : ``` TypeError: Cannot read proDoes tRPC works in application network layer (HTTP) or transport network layer (TCP, UDP)?Just wondering if tRPC uses TCP under the hood.returning undefined from server gets stripped on the clientI encounter this issue when working with TRPC React under a Turborepo. But I works fine on Next I sTypeScript, Mono-Repositories and Internal Packages / Project ReferencesI am getting quite frustrate with project references / internal projects and the resolving of types how to integrate with Redis (ioredis)Any middleware?Help to deploy my TRPC proj from a monorepo (turborepo) at VercelI'm trying to learn monorepo with TRPC, both are new for me and Im kind struggling to deploy it becaTRPC ratelimiting endpointsI am currently having some problems with a race condition in my TRPC nextJS api. Essentially what iexpress-session for tRPCI am using express-session for all my servers to create session authentication. Is there something next-prisma-websockets-starter seeds twice on 'pnpm dx'Hi, i'm using this starter template for my app. The `dx` script from package.json runs both `prisma Can you return from an API endpoint before a sync operation is complete?I'm curious, if I have an endpoint that saves something to a DB and I choose to return from the endpuseInfiniteQueryHey i saw on trpc docs that it is used with prisma, but can i so it with drizzle ? How to past cursoTRPC Next/Server Types Broken >10.5.0Hi all, recently I upgraded from 10.5.0 to latest 10.21.2, discovering that I now have type-check erJWT Token is type "never" in frontend.??!!TRPC Backend is sending JWT Token as string but frontend is reading it as type "never". I am using tHow to properly check the contents of prefetched data?I have dynamic route with SSG and if coming product slug is not in db I want to return notFound: trutrpc/next very slowI have set up my project using trpc/next and i have extremely slow queries, simple hello world takinGeneric handler for data.isLoading and data.isErrorHi, I'm looking for a way to create generic interface for useQuery result (budgetData from example b