Finn
Finn
TtRPC
Created by Finn on 3/1/2024 in #❓-help
How to properly handle Prima selects/includes with tRPC?
Hello, my understanding of optimizing procedures to be the most efficient would be to enable one procedure to handle different use-cases. So I'd like a procedure like getById to take a list that allows all possible attributes from the prisma models and optionally a list of models to include. Currently, I define a list of all attributes on a global level for each router, that includes all includable Fields (I'd then do the same for the selectable fields). But that - even with just the includable fields - ends in this madness:
const includableFields = z.enum([
"comments",
"readingProgress",
"novelInsights",
"author",
"userLists",
// ...
]);

export const novelRouter = createTRPCRouter({
getById: privateProcedure
.input(
z.object({
id: z.string(),
include: z.array(includableFields).optional(),
})
)
.query(async ({ ctx, input }) => {
return await ctx.db.novel.findUnique({
where: {
id: input.id,
},
include: {
comments: input.include?.includes("comments") ?? false,
readingProgress:
input.include?.includes("readingProgress") ?? false,
novelInsights:
input.include?.includes("novelInsights") ?? false,
author: input.include?.includes("author") ?? false,
userLists: input.include?.includes("userLists") ?? false,
chapters: input.include?.includes("chapters") ?? false,
genre: input.include?.includes("genre") ?? false,
customInsights:
input.include?.includes("customInsights") ?? false,
},
});
}),
});
const includableFields = z.enum([
"comments",
"readingProgress",
"novelInsights",
"author",
"userLists",
// ...
]);

export const novelRouter = createTRPCRouter({
getById: privateProcedure
.input(
z.object({
id: z.string(),
include: z.array(includableFields).optional(),
})
)
.query(async ({ ctx, input }) => {
return await ctx.db.novel.findUnique({
where: {
id: input.id,
},
include: {
comments: input.include?.includes("comments") ?? false,
readingProgress:
input.include?.includes("readingProgress") ?? false,
novelInsights:
input.include?.includes("novelInsights") ?? false,
author: input.include?.includes("author") ?? false,
userLists: input.include?.includes("userLists") ?? false,
chapters: input.include?.includes("chapters") ?? false,
genre: input.include?.includes("genre") ?? false,
customInsights:
input.include?.includes("customInsights") ?? false,
},
});
}),
});
The problem I have with this, is that it looks horrendous and needs to be manually adjusted everytime the schema changes
8 replies
TtRPC
Created by Finn on 1/30/2024 in #❓-help
How do I setup subscriptions with websockets in Next.js 14 app router?
All I've found were some older examples for the pages router which for me were not very understandable or I'm just stupid. For the most part I'm having trouble understanding how exactly the websocket server is started. Does it start with Next.js or is it something that you have to seperatly? Would be glad if someone can give me some insight.
6 replies
TtRPC
Created by Finn on 1/29/2024 in #❓-help
Using tRPC in Next.js Middleware
Hello, I am quite new to tRPC so forgive me if I'm asking something quite obvious/dumb. I was introduced to tRPC by the t3-stack, that I discovered when I started with Next.js. Now onto the question. I am storing user session inside a database and want to validate a user that has a session_token cookie by its value. So, the value of the cookie needs to exist in the database. That way I can authenticate the request as well as associate a user. The problem I was facing is that I was having a hard time trying to access tRPC routes from the Next.js middleware. The t3 stack came with a pre-configured tRPC server and react client. Both of them do not work inside the Next.js middleware, because it runs on the Edge runtime. I have found some posts here that were asking a similar question, but none of them gave me an answer for my question. One of the posts helped solving the problem by suggesting to create a new client with a httpBatchLink that points to the api/trpc route. And that works the way it's suppose to. But right now, I export 3 api variables:
// src/trpc/react.tsx
export const api = createTRPCReact<AppRouter>();
// src/trpc/react.tsx
export const api = createTRPCReact<AppRouter>();
// src/trpc/server.ts
const createContext = cache(() => {
const heads = new Headers(headers());
// ...
});

export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
// ...
() =>
({ op }) =>
observable((observer) => {
createContext()
// ...
}),
],
});
// src/trpc/server.ts
const createContext = cache(() => {
const heads = new Headers(headers());
// ...
});

export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
// ...
() =>
({ op }) =>
observable((observer) => {
createContext()
// ...
}),
],
});
// src/trpc/edge.ts
export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
fetch(url, options) {
return fetch(url, {
...options,
});
},
}),
],
});
// src/trpc/edge.ts
export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
fetch(url, options) {
return fetch(url, {
...options,
});
},
}),
],
});
Would you say, that what I've done is okay, or am I doing something completely unnecessary here?
16 replies