T
tRPC

❓-help

[HOW TO?] Call trpc endpoints from vanilla nextJs api routes

TLTrader Launchpad5/11/2023
Spinoff from an og thread here: https://discordapp.com/channels/867764511159091230/1032301198990135347 HI! I am wanting to do the same thing...call a trpc route from within a nextjs public api endpoint. I am using a fresh t3-turbo-with-clerk project which has trpc in packages/api (@acme/api) here is my apps/nextjs/src/pages/api/post.ts file
import { NextApiRequest, NextApiResponse } from "next";
import { appRouter } from "@acme/api";
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
import { TRPCError } from "@trpc/server";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const caller = appRouter.createCaller({});

try {
const result = await caller.post.all();
res.status(200).json(result);
} catch (e) {
console.error(e);
const code = e instanceof TRPCError ? getHTTPStatusCodeFromError(e) : 500;
res.status(code).json({ error: e });
}
};

export default handler;
import { NextApiRequest, NextApiResponse } from "next";
import { appRouter } from "@acme/api";
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
import { TRPCError } from "@trpc/server";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const caller = appRouter.createCaller({});

try {
const result = await caller.post.all();
res.status(200).json(result);
} catch (e) {
console.error(e);
const code = e instanceof TRPCError ? getHTTPStatusCodeFromError(e) : 500;
res.status(code).json({ error: e });
}
};

export default handler;
TLTrader Launchpad5/11/2023
i am getting a type error on
const caller = appRouter.createCaller({});
const caller = appRouter.createCaller({});
Argument of type '{}' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.
Argument of type '{}' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.
and when i load the page i get a json error:
{"error":{"code":"INTERNAL_SERVER_ERROR","name":"TRPCError"}}
{"error":{"code":"INTERNAL_SERVER_ERROR","name":"TRPCError"}}
Can someone assist me with the issue? I know I could use https://github.com/jlalmes/trpc-openapi to expose routes, I just wanted to get a basic example working first and then look into that. I am only exposing routes atm for testing purposes from what I can see, const caller = appRouter.createCaller({}); needs a ctx parameter. my @acme/api/index.ts file has
export type { AppRouter } from "./src/router";
export { appRouter } from "./src/router";

export { createContext } from "./src/context";
export type { Context } from "./src/context";
export type { AppRouter } from "./src/router";
export { appRouter } from "./src/router";

export { createContext } from "./src/context";
export type { Context } from "./src/context";
Nnlucas5/11/2023
Have you looked at our nextjs docs? https://trpc.io/docs/nextjs/introduction
TLTrader Launchpad5/11/2023
Nnlucas5/11/2023
You shouldn't need createCaller We have serverside helpers Problem looks like you're not actually creating the necessary ctx object but you shouldn't need to do it here
TLTrader Launchpad5/11/2023
the documentation explains using createCaller for nextjs api endpoints via that link above. Why wouldnt I need it? I have used the SSG helper in a pages/post/[id].tsx page, but didnt think that was the correct way to use it in an API route per the trpc documentation
Nnlucas5/11/2023
Got it, I'm not really a user of next, but yes looks like we do recommend that in some situations You'll need to call your createContext function {} is not enough
TLTrader Launchpad5/11/2023
ok, and in that function it expects some parameters (auth). However isnt the context object already set up inside @acme/api somewhere? Here is my pages/dashboard page where I load the posts into a flashlist:
import { HomeScreen as FeatureHomeScreen } from "@acme/app/features/home/screen";
import MainLayout from "@acme/app/layouts/MainLayout";
export default function HomeScreen() {
return <FeatureHomeScreen />;
}
import { HomeScreen as FeatureHomeScreen } from "@acme/app/features/home/screen";
import MainLayout from "@acme/app/layouts/MainLayout";
export default function HomeScreen() {
return <FeatureHomeScreen />;
}
Nnlucas5/11/2023
createContext is called by the adapter, but createCaller makes your calling code into the adapter That first parameter is the context values
TLTrader Launchpad5/11/2023
screens are located in packages/app/features (@acme/app) and here is the Homescreen linked from above file
import React from "react";

import { Link } from "solito/link";
import { Button, TouchableOpacity } from "../../design/button";
import { Text } from "../../design/typography";
import { View, SafeAreaView } from "../../design/view";

import type { AppRouter } from "@acme/api";
import type { inferProcedureOutput } from "@trpc/server";

import { trpc } from "../../utils/trpc";
import { FlashList } from "@shopify/flash-list";


export function HomeScreen() {
const { data: postData, isLoading, error } = trpc.lesson.all.useQuery();
.........
import React from "react";

import { Link } from "solito/link";
import { Button, TouchableOpacity } from "../../design/button";
import { Text } from "../../design/typography";
import { View, SafeAreaView } from "../../design/view";

import type { AppRouter } from "@acme/api";
import type { inferProcedureOutput } from "@trpc/server";

import { trpc } from "../../utils/trpc";
import { FlashList } from "@shopify/flash-list";


export function HomeScreen() {
const { data: postData, isLoading, error } = trpc.lesson.all.useQuery();
.........
trpc works fine on this page and loads the posts. Do i need to re-import clerk modules on pages/api/post to rebuild context? i would think i could import context from @acme/api, then insert it into createCaller() and yes i do believe context is the issue with my code because of the error:
Argument of type '{}' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.
Argument of type '{}' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.
but it is asking for ctx to have auth (clerk) and prisma, which id either have to import again or re-use from @acme/api here is another github I have also been looking at: https://github.com/trpc/trpc/issues/1724 this is code for the openapi generator that we should be able to pull some code from to assist. This is where I got the understanding that createCaller needs a ctx object and that ceateContext probably needs to be imported...but this is as far as I have got so atm in my pages/api/posts.ts i have (shorted for brevity)
.....
import { createContext } from "@acme/api/";

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>,
) {
const { method } = req;

switch (method) {
case "GET":
try {
const ctx = await createContext({ req, res });
const caller = appRouter.createCaller({ ctx });
const data = await caller.post.all();
console.log(data);
...
.....
import { createContext } from "@acme/api/";

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>,
) {
const { method } = req;

switch (method) {
case "GET":
try {
const ctx = await createContext({ req, res });
const caller = appRouter.createCaller({ ctx });
const data = await caller.post.all();
console.log(data);
...
and I am still getting error
Argument of type '{ ctx: { auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }; }' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.
Argument of type '{ ctx: { auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }; }' is not assignable to parameter of type '{ auth: SignedInAuthObject | SignedOutAuthObject; prisma: PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined>; }'.

Looking for more? Join the community!

Recommended Posts
Tutorial for setting up tRPC with Next13 app dir?Anyone has a goos tutorial (blogpost / YouTube) on setting up tRPC with Next13 app dir for both clieStack trace in Client?I've just found that in production I can see stack trace for TRPCErrors. Isin't it supposed to not sSequential batch mutationHow one would make a mutation as a sequential mutation batch call? Say I have to add 10 apples to thHave middleware require a "base" inputIs there a way to have middleware add a minimum required input, like an org id? So that every procedIs it possible to dynamically change the url of httpBatchLink in runtime?I need to do it because I have 2 domians that share the same NextJS project and I need to be able togetting manually a subdomainFor some reason I can fetch here the route /test, but not /tester/eAbility to perform a tRPC request form a terminal, curl-likeHey, I wanted to ask if there is conventional a way to do that? I wanted to warmup my lambda but canUsage of useQuery after pageload?Hi all! I am new to TRPC so my apologies in advance for a very nooby question: In my [id].tsx file ISecurity question about tRCPIf I export the tRCP router as type in order to import that type in my client JS, wouldn't it mean tReal-world Large Application Examples?Are there any OSS examples (besides cal.com) demonstrating large tRPC code bases? I want to see howScaling tRPCI’ve been seeing issues regarding tRPC routers and performance issues as routers grow. I’m wonderinwhat is the best way to update trpc and its dependencies?Hi all, as the title says, how can i best update trpc and its dependencies? TRPC stands at 10.25.1,Where i can read a journal about tRPC ?I use tRPC for my Final Task in my Bachelor Degree, but i can't found journal about tRPC. Can anyoneDefault Query Function to resume paused mutationsI'm building a React Native App with an offline mode. I implemented a PersistQueryProvider and a buiSuperJSON is wrapping results in type with keys "json" and "meta"How can I modify the transformer in SuperJSON library to only return the "json" property and ignore Caching(?) previous data until query returns new datawhen I update my useQuery inputs with new filters it instantly sets the data to `undefined` while thHow to upload file not use S3 Next js? Please, examplefile: course.router.ts / import { CourseSchema } from "~/schema/post.schema"; import { createTRPChow can i send a request to specific route in trpc server, after mutation ?i am using trpc with next js ,Help in deploymentHey all, I am building an app which is having a 1 . vite-react frontend 2 . trpc-standalone how to persist the query client?I want to persist the trpc query client cache, but don't want to create a new query client, I want t