ค้นหาเว็บไซต์

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
    }
  })
})