MiNiMAL
MiNiMAL
TtRPC
Created by MiNiMAL on 11/2/2023 in #❓-help
Function to release context post-batching?
In our application every customer has their own schema, therefore we need a db client per request which I was hoping to leverage with TRPC context. Ideally, we'd be able to: - Connect to the database in context ✅ - Set the search_path to match the client's JWT in context ✅ - Run our procedures using that database connection from context ✅ - Release the database connection after all batching is finished ❌ Is this not currently possible with TRPC? Right now I think I can only connect to the database using a per procedure middleware.
const db = // connect to db

await db.execute('SET search_path=...')

try {
return await next({ ctx: { ...opts.ctx, db } })
} catch () {
// release connection
} finally {
// release connection
}
const db = // connect to db

await db.execute('SET search_path=...')

try {
return await next({ ctx: { ...opts.ctx, db } })
} catch () {
// release connection
} finally {
// release connection
}
This works, but it requires establishing a connection/search_path for every procedure in a batch, instead of just once in context and releasing after the batch. Is there a way to accomplish this?
13 replies
TtRPC
Created by MiNiMAL on 10/15/2023 in #❓-help
Dynamic input not leading to changes on the front end
I'm building a dynamic procedure to access my database via Drizzle ORM. Ideally a developer would be able to send input parameters to the procedure and have it's output adjusted by that input. For example, in the below, I have a table called demotable which has an updatedAt column. If a developer passes in columns: { updatedAt: false } to the procedure, then ideally the column would not get included in the result. If I hard code the columns parameter in the backend itself, then it works great. Is there a way to accomplish this for the full round trip?
// Inferring type for the findMany argument
type FindManyArg = Parameters<DB['query']['demotable']['findMany']>[0]

// ...

//Setting up the procedure
discordTest: privateProcedure
.input(input => input as FindManyArg)
.query(async ({ input }) => {
const result = await db.query.demotable.findMany(input)
return result
}),

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({
columns: { updatedAt: false }, // <== this is properly typed and intellisense is working
})
console.log(demo?.[0].updatedAt) // <=== does not error

// ============================

// Hardcoding columns does properly reflect on the front end
const result = await db.query.demotable.findMany({
...input,
columns: { updatedAt: false },
})
return result

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({})
console.log(demo?.[0].updatedAt) // <=== errors as expected
// Inferring type for the findMany argument
type FindManyArg = Parameters<DB['query']['demotable']['findMany']>[0]

// ...

//Setting up the procedure
discordTest: privateProcedure
.input(input => input as FindManyArg)
.query(async ({ input }) => {
const result = await db.query.demotable.findMany(input)
return result
}),

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({
columns: { updatedAt: false }, // <== this is properly typed and intellisense is working
})
console.log(demo?.[0].updatedAt) // <=== does not error

// ============================

// Hardcoding columns does properly reflect on the front end
const result = await db.query.demotable.findMany({
...input,
columns: { updatedAt: false },
})
return result

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({})
console.log(demo?.[0].updatedAt) // <=== errors as expected
4 replies
TtRPC
Created by MiNiMAL on 10/11/2022 in #❓-help
Best practices for implementing an offline application
Hey there! I'm building a full stack react-native app with Expo and a tRPC backend. I'd like for this app to be functional offline. Currently I'm accomplishing this via a simple optimistic update like:
const createUser = trpc.userCreate.useMutation({
onMutate: async () => {
// Cancel users fetch
await utils.users.cancel()
// Get current users list
const previousData = utils.users.getData() || []
// Append new user
utils.users.setData([...previousData, { id: uuid.v1(), name } as User])
return { previousData }
},
})
const createUser = trpc.userCreate.useMutation({
onMutate: async () => {
// Cancel users fetch
await utils.users.cancel()
// Get current users list
const previousData = utils.users.getData() || []
// Append new user
utils.users.setData([...previousData, { id: uuid.v1(), name } as User])
return { previousData }
},
})
This is working pretty well (it's late and I plan on extensively testing this tomorrow). I'd like to confirm what best practices, if any, have been established by the community before continuing.
2 replies