reactjs - Hantera middleware i tRPC, anropa flera metoder för en rutt?


Jag gör ett grupprojekt som vi bara har ett par veckor på oss att slutföra. Vi har beslutat att använda T-3 stacken och har valt tRPC för att bygga servern. Jag är bara bekant med Express och har inte hittat mycket hjälp online för att lära mig tRPC. Jag har några grundläggande metoder som fungerar, till exempel att returnera "hej användare" från backend när det anropas från frontend. Vår applikation kommer att ansluta till en användardatabas och jämföra inskickade SQL-frågor och returnera statistik om dessa frågor.

Jag har problem med att bygga mer komplexa rutter på backend, jag verkar inte kunna lista ut hur man kallar flera middleware i samma router.

Här är ett exempel på en liknande applikation och hur deras express-server ser ut när den router och anropar de olika mellanvarorna:

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

Detta är början på min tRPC-router, hur skulle jag anropa flera metoder för samma rutt på det sätt som exemplet ovan använder middleware och router?

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

Hur skulle jag designa en rutt som kallade på var och en av dessa metoder på denna exempelrouter? Tror du att vi borde fortsätta med tRPC eller är det bättre att vi byter till express för att slutföra projektet?

Svar #1

Du kommer att behöva extrahera logiken från varje av de olika procedurerna som du vill ha. Detta har rekommenderats av en av underhållarna av trpc, eftersom det inte rekommenderas att anropa trpc-procedurer från andra procedurer.

Här är en video och runt den angivna tidsstämpeln börjar han faktiskt använda denna metod för separation nedan. Det kanske inte verkar bäst att separera det på det här sättet eftersom du är tidigt i ditt projekt, men när du har flera routrar och behöver kunna hämta information från andra routrar kommer du att börja se fördelen.

Jag skulle också rekommendera att gå med i trpc-discorden och Theos discord och söka i båda, det har hjälpt mig mycket.

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