t3-oss / create-t3-app

The best way to start a full-stack, typesafe Next.js app
https://create.t3.gg
MIT License
25.45k stars 1.17k forks source link

bug: Problems using example in docs for exposing tRPC procedures externally #1749

Open a1031 opened 9 months ago

a1031 commented 9 months ago

Provide environment information

System: OS: macOS 14.2.1 CPU: (8) arm64 Apple M2 Memory: 97.97 MB / 24.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node Yarn: 1.22.21 - /opt/homebrew/bin/yarn npm: 10.2.5 - ~/.nvm/versions/node/v20.10.0/bin/npm

ct3aMetadata.initVersion: 7.26.0 Next.js: 14.1.0 (using App Router)

Describe the bug

I've used create-t3-app@7.26.0 to scaffold a project and am trying to expose certain tRPC procedures externally (so that they can be invoked via Vercel Cron jobs).

Based on the Expose a single procedure externally example, when I create a file called src/app/api/test/[id].ts and include this:

import { type NextApiRequest, type NextApiResponse } from "next";
import { appRouter, createCaller } from "../../../server/api/root";
import { createTRPCContext } from "../../../server/api/trpc";

const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => {
  // Create context and caller
  const ctx = await createTRPCContext({ req, res });
  const caller = createCaller(ctx);
  try {
    const { id } = req.query;
    const user = await caller.user.getById(id);
    res.status(200).json(user);
  } catch (cause) {
    if (cause instanceof TRPCError) {
      // An error from tRPC occurred
      const httpCode = getHTTPStatusCodeFromError(cause);
      return res.status(httpCode).json(cause);
    }
    // Another error occurred
    console.error(cause);
    res.status(500).json({ message: "Internal server error" });
  }
};

export default userByIdHandler;

I get 13 TypeScript errors, most significantly:

  1. Module '"../../../server/api/root"' has no exported member 'createCaller'. on line 2, col 21

    • For this I have confirmed that the path points to src/server/api/root.ts
    • I have not modified src/server/api/root.ts from the original version and it looks like this - there is indeed no createCaller export:

      import { postRouter } from "~/server/api/routers/post";
      import { createTRPCRouter } from "~/server/api/trpc";
      
      /**
      * This is the primary router for your server.
      *
      * All routers added in /api/routers should be manually added here.
      */
      export const appRouter = createTRPCRouter({
      post: postRouter,
      });
      
      // export type definition of API
      export type AppRouter = typeof appRouter;
  2. Object literal may only specify known properties, and 'req' does not exist in type '{ headers: Headers; }'. on line 7, col 41
  3. Cannot find name 'TRPCError'. Did you mean 'RTCError'? on line 14, col 26
    • This is fixed by importing the error type:
      import { TRPCError } from '@trpc/server';
  4. Cannot find name 'getHTTPStatusCodeFromError'. on line 16, col 24
    • This is fixed by importing the helper function:
      import { getHTTPStatusCodeFromError } from '@trpc/server/http';

      Since I've only ever used the Next.js App Router and not the pages router, as a troubleshooting step I've tried scaffolding a new project using pages router, but that also has the same issues.

I've also pored over https://github.com/t3-oss/create-t3-app/issues/1709, https://github.com/t3-oss/create-t3-app/pull/1721, and https://github.com/t3-oss/create-t3-app/pull/1721/commits/c603e65581426890b06b1f678e291066fb7ce61a many times trying to figure out where createCaller() is and createCallerFactory() is implemented.

Reproduction repo

https://codesandbox.io/p/devbox/mn5qf3?file=%2Ftest%2Fsrc%2Fapp%2Fapi%2Ftest%2F%5Bid%5D.ts%3A3%2C10

To reproduce

  1. Open the test/src/app/api/test/[id].ts file in the CodeSandbox devbox.
  2. Wait for the TS server to initialize
  3. Observe the TypeScript errors: image

Additional information

I'm not familiar with the internals of create-t3-app or tRPC well enough to know whether this is just a documentation issue, or if there's actually something missing from the create-t3-app template which is intended to be there.

riccardolardi commented 2 months ago

Wouldn't you need to create a route handler instead? https://nextjs.org/docs/app/building-your-application/routing/route-handlers