reactjs - การจัดการมิดเดิลแวร์ใน tRPC, การเรียกหลายเมธอดสำหรับเส้นทางเดียว?
ฉันกำลังทำโปรเจกต์กลุ่มซึ่งเรามีเวลาเพียงไม่กี่สัปดาห์ในการทำให้เสร็จ เราได้ตัดสินใจที่จะใช้สแตก T-3 และได้เลือก tRPC ในการสร้างเซิร์ฟเวอร์ ฉันคุ้นเคยแค่กับ express และยังไม่พบข้อมูลช่วยเหลือมากนักในการเรียนรู้ tRPC ฉันมีวิธีการพื้นฐานบางอย่างในการทำงาน เช่น การส่งค่ากลับเป็น "hello user" จากแบ็คเอนด์เมื่อเรียกจากฟรอนต์เอนด์ แอปพลิเคชันของเราจะเชื่อมต่อกับฐานข้อมูลผู้ใช้และเปรียบเทียบคำสั่ง SQL ที่ป้อนเข้าไป พร้อมส่งผลเมตริกส์เกี่ยวกับคำสั่งเหล่านั้น
ฉันกำลังประสบปัญหาในการสร้างเส้นทางที่ซับซ้อนมากขึ้นบนแบ็คเอนด์ ฉันดูเหมือนจะไม่สามารถหาวิธีเรียกใช้มิดเดิลแวร์หลายตัวในเราเตอร์เดียวกันได้
นี่คือตัวอย่างของแอปพลิเคชันที่คล้ายกันและลักษณะของเซิร์ฟเวอร์ Express ของพวกเขาเมื่อทำการ routing และเรียกใช้งาน middleware ต่างๆ:
const router = Router();
// check if database being added is valid
// WIP
router.post(
'/uri',
connectController.connectDB,
connectController.createExtension,
databaseController.dbStats,
(req, res) => {
console.log(res.locals);
return res.status(200).json(res.locals);
}
);
// delivers metrics from database
// notice: the database controllers will console log, but not return errors so that individual charts can render
router.post(
'/queryMetrics',
connectController.connectDB,
connectController.createExtension,
databaseController.queryTimes,
databaseController.numOfRows,
databaseController.topCalls,
databaseController.dbStats,
databaseController.cacheHitRatio,
databaseController.statActivity,
(req, res) => {
return res.status(200).json(res.locals.result);
}
);
นี่คือจุดเริ่มต้นของตัวจัดการเส้นทาง tRPC ของฉัน ฉันจะเรียกใช้หลายเมธอดสำหรับเส้นทางเดียวกันได้อย่างไรในแบบที่ตัวอย่างข้างต้นใช้มิดเดิลแวร์และตัวจัดการเส้นทาง?
export const exampleRouter = createTRPCRouter({
hello: publicProcedure
.input(z.object({ text: z.string() }))
.query(({ input }) => {
return {
greeting: `Hello ${input.text}`,
};
}),
getAll: publicProcedure.query(async ({ ctx }) => {
// return ctx.prisma.user.findMany();
console.log(ctx.session)
const users = await ctx.prisma.user.findMany();
const names = users.map(user => user.name);
return names;
}),
getSecretMessage: protectedProcedure.query(() => {
return "you can now see this secret message!";
}),
connectToUserDb: protectedProcedure
.input(z.object({ URI: z.string() }))
.query( ({input, ctx}) => {
const pool = new Pool({
connectionString: input.URI
});
pool.query('SELECT NOW()', (error, result) => {
if (error) {
console.error('Error executing query:', error);
return;
}
console.log('Connection to "postgres" database successful');
console.log('Current timestamp:', result.rows[0].now);
});
ctx.dbConnection = pool;
})
ฉันจะออกแบบเส้นทางที่เรียกใช้แต่ละวิธีในตัวอย่าง router นี้ได้อย่างไร คุณคิดว่าเราควรทำต่อกับ tRPC หรือเราควรเปลี่ยนไปใช้ express เพื่อทำโปรเจกต์ให้เสร็จดีขึ้น
คำตอบ #1
คุณจะต้องดึงตรรกะจากแต่ละขั้นตอนที่คุณต้องการ นี่คือสิ่งที่ได้รับคำแนะนำจากหนึ่งในผู้ดูแลของ trpc เนื่องจากไม่แนะนำให้เรียกใช้ขั้นตอนของ trpc จากขั้นตอนอื่น
นี่คือวิดีโอและประมาณเวลาที่ลิงก์ไว้เขาเริ่มใช้วิธีการแยกนี้จริง ๆ อาจไม่ดูเหมาะที่สุดที่จะทำการแยกออกแบบนี้ตั้งแต่เนิ่น ๆ ในโครงการของคุณ แต่เมื่อคุณมีเราเตอร์หลายตัว และคุณจำเป็นต้องสามารถดึงข้อมูลจากเราเตอร์ตัวอื่น คุณจะเริ่มเห็นประโยชน์
ฉันก็ขอแนะนำให้เข้าร่วม Discord ของ trpc และ Discord ของ Theo แล้วค้นหาในทั้งสองที่ มันช่วยฉันได้มาก
const helloLogic = () => {
greeting: `Hello ${input.text}`,
};
const getAllLogic = async ({ prisma }) => {
console.log(ctx.session)
const users = await ctx.prisma.user.findMany();
const names = users.map(user => user.name);
return names;
};
export const exampleRouter = createTRPCRouter({
hello: publicProcedure
.input(z.object({ text: z.string() }))
.query(({ input }) => {
return helloLogic();
}),
getAll: publicProcedure.query(async ({ ctx }) => {
return await getAllLogic()),
}),
// ** Everything you need procedure **
callAllMethods: publicProcedure.query(async ({ ctx }) => {
return {
hello: helloLogic(),
users: await getAllLogic()
// Whatever else you need to call
}
})
})
