Ignition 98
Ignition 989mo ago

Difference between createTRPCNextAppDirServer, createTRPCNext and createTRPCProxyClient?

Hey everyone. I struggle to understand the difference between these 3 TRPC functions when it come to using it in server.ts to be able to make server side API calls. I'm using NextJS 14 and app router. Is there clear differentiation between these 3? This project is for a production release. Would greatly appreciate a little break down. Thanks!
13 Replies
DxD
DxD9mo ago
I belive you are talking about initTRPC, initTRPCBrowser, and initTRPCServer, right ?
Ignition 98
Ignition 989mo ago
I'm referring to step 3 from the docs. https://trpc.io/docs/server/data-transformers Currently I'm using the following structure to make server side calls to my database:
export const api = createTRPCProxyClient<AppRouter>({
transformer: superjson, // <--
// [...]
});
export const api = createTRPCProxyClient<AppRouter>({
transformer: superjson, // <--
// [...]
});
export default async function Home() {
const hello = await api.post.hello.query({ text: "from tRPC" });
return (
<p className="text-2xl text-white">
{hello ? hello.greeting : "Loading tRPC query..."}
</p>
)
}
export default async function Home() {
const hello = await api.post.hello.query({ text: "from tRPC" });
return (
<p className="text-2xl text-white">
{hello ? hello.greeting : "Loading tRPC query..."}
</p>
)
}
I don't quite get what benefit I'd get if I was to use createTRPCNextAppDirServer or createTRPCNext instead of createTRPCProxyClient as all of them are capable of making server side calls.
Data Transformers | tRPC
You are able to serialize the response data & input args. The transformers need to be added both to the server and the client.
DxD
DxD9mo ago
The difference between createTRPCProxyClient, createTRPCNext, and createTRPCNextAppDirServer lies in their use cases and intended usage scenarios. createTRPCProxyClient: Use Case: This is intended for client-side usage. It allows you to create a client proxy that can be used on the client to make tRPC queries. It's suitable for scenarios where you need to make requests from the client to the server. createTRPCNext: Use Case: This is designed for server-side usage within Next.js API routes. It provides an instance of TRPCClient specifically configured for server-side rendering (SSR) within Next.js. createTRPCNextAppDirServer: Use Case: This is a variant of createTRPCNext but is specifically intended for server rendering within Next.js when your api directory is within your app directory. In summary Use createTRPCProxyClient for client-side usage. Use createTRPCNext for server-side rendering within Next.js API routes. Use createTRPCNextAppDirServer if your API directory is within your app directory and you want server-side rendering in that specific setup. I hope it helps Also, have u ever create a full auth system with trpc next and jwt ?
Ignition 98
Ignition 989mo ago
Thanks a lot for the detailed answer! No, I haven't. That's what I'm trying to do atm with Next, TRPC and Supabase Auth.
DxD
DxD9mo ago
Any time Ohh…I am trying for days And nothing
Ignition 98
Ignition 989mo ago
Also Supabase setup?
DxD
DxD9mo ago
No, I use mongodb
Ignition 98
Ignition 989mo ago
What are you having problems with?
DxD
DxD9mo ago
After I log in, I can not send my custom headers to my context With that context I check if user has a token And then he can access protected procedures If u solve auth…can u share the git ?
Ignition 98
Ignition 989mo ago
Sure
DxD
DxD9mo ago
@Ignition 98
import { TRPCError } from '@trpc/server';
import { db } from 'db';
import jwt from 'jsonwebtoken';
import { checkSamePassword } from 'utils/hash/checkSamePassword';
import keys from 'utils/secret/keys';
import { z } from 'zod';

import { router, publicProcedure } from '..';

export const loginRouter = router({
login: publicProcedure
.input(
z.object({
email: z.string().nonempty('Email is required').email('Invalid email address'),
password: z.string().nonempty('Password is required').min(6),
}),
)
.query(async ({ ctx, input: { email, password } }) => {
const user = await db.user.findOne({ email: email });

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const validatePassword = await checkSamePassword(password, user?.password);
if (!user || !validatePassword) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Email or password is not valid, please try again.',
});
} else {
const token = jwt.sign({ _id: user._id }, keys.jwtSecret, { expiresIn: '1h' });
const refreshToken = jwt.sign({ _id: user._id }, keys.jwtSecret, { expiresIn: '1h' });

ctx.res.cookie('access_token', refreshToken, {
httpOnly: true,
secure: true,
});

return {
// headers: {
// authorization: `Bearer ${token}`,
// },
data: {
token,
},
};
}
}),
});
import { TRPCError } from '@trpc/server';
import { db } from 'db';
import jwt from 'jsonwebtoken';
import { checkSamePassword } from 'utils/hash/checkSamePassword';
import keys from 'utils/secret/keys';
import { z } from 'zod';

import { router, publicProcedure } from '..';

export const loginRouter = router({
login: publicProcedure
.input(
z.object({
email: z.string().nonempty('Email is required').email('Invalid email address'),
password: z.string().nonempty('Password is required').min(6),
}),
)
.query(async ({ ctx, input: { email, password } }) => {
const user = await db.user.findOne({ email: email });

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const validatePassword = await checkSamePassword(password, user?.password);
if (!user || !validatePassword) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Email or password is not valid, please try again.',
});
} else {
const token = jwt.sign({ _id: user._id }, keys.jwtSecret, { expiresIn: '1h' });
const refreshToken = jwt.sign({ _id: user._id }, keys.jwtSecret, { expiresIn: '1h' });

ctx.res.cookie('access_token', refreshToken, {
httpOnly: true,
secure: true,
});

return {
// headers: {
// authorization: `Bearer ${token}`,
// },
data: {
token,
},
};
}
}),
});
any idea why is not store in cookie ?
DxD
DxD9mo ago
No description
Ignition 98
Ignition 989mo ago
No idea tbh..