Vilian
Vilian2y ago

context question

Why are the context examples only showing opinionated examples with next/react auth ? Also i find it very confusing that it is not mentioned in the docs what kind of arguments the context function is called with.
28 Replies
Nick
Nick2y ago
Feel free to write up your thoughts here: https://github.com/trpc/trpc/discussions/3963
GitHub
RFC: 2023 Upgraded Documentation · trpc trpc · Discussion #3963
Preface Currently the docs have a lot of really well written content, and some which needs a little love. The biggest problem is they're often written from the perspective of APIs, rather than ...
Nick
Nick2y ago
We're actively working on improvements so this is very appreciated 🙂
Vilian
VilianOP2y ago
That is great and all, but do you think you can help me understand what is the proper way to type a context function? What should be the type of an object that is able to be passed to a procedure's use method ?
Vilian
VilianOP2y ago
Nick
Nick2y ago
t.middleware()
Vilian
VilianOP2y ago
So wait, i'm a bit confused What exactly is the difference between context and middleware?
Nick
Nick2y ago
Context is a place to put data and functionality that procedures need to use Middleware is a place to put behaviour which gets called before a procedure is called, and can also modify the Context
Vilian
VilianOP2y ago
So if i'm understanding this correctly, context -> middleware -> procedure
Nick
Nick2y ago
It might be helpful to look through the example projects as they have implementations of this Context is available to both middlewares and procedures
Vilian
VilianOP2y ago
Middleware can be specific to a procedure, but a context is router wide, is that correct?
Nick
Nick2y ago
So createContext will be API-wide, yes Middlewares are attached to a procedure yes Middlewares which modify context only modify the context for procedures on that base procedure
Vilian
VilianOP2y ago
I see. Last question is How do i attach a context to a router? Or do i need to attach it to the createHttpServer instead? Also another valid question that is derivative of my previous one would be: Is it possible to attach contexts to routers that are later on going to be merged together, which would result in some of the api routes not having context ?
Vilian
VilianOP2y ago
Sidenote:
Vilian
VilianOP2y ago
This image seems to suggest that contexts are api wide, regardless if i want to merge in routers that have no use for these contexts with others that actually do
Nick
Nick2y ago
That’s where the logic should be passed, yes. Typescript will tell you what the args and result are
Vilian
VilianOP2y ago
Is there a type for the createContext object, so i can define it elsewhere in my code and not inline of the createHttpServer?
Nick
Nick2y ago
All routers come from t.router which already has the Context type associated. createContext then needs writing once Hover over it in your editor and you’ll see the type
Vilian
VilianOP2y ago
Vilian
VilianOP2y ago
Ughm... i think i'm not explaining what i want clearly enough.
const createContext: TypeHere = () => {
return {};
};

export const startTRPC = () => {
createHTTPServer({
middleware: cors(),
router: appRouter,
createContext
}).listen(config.PORT);
};
const createContext: TypeHere = () => {
return {};
};

export const startTRPC = () => {
createHTTPServer({
middleware: cors(),
router: appRouter,
createContext
}).listen(config.PORT);
};
the TypeHere is what i am looking for.
Nick
Nick2y ago
You can either dig into that type and understand what tRPC is doing, or you can write out the bits you actually need into a factory createContext: (req, res) => makeMyContext(req.etc)
Vilian
VilianOP2y ago
Isn't there an already exported type for the createContext option of the createHTTPServer?
Nick
Nick2y ago
Feel free to open an issue about it, it's not a problem I've ever needed to solve The docs I think do some of this, but not using a dedicated type
Vilian
VilianOP2y ago
But i think you get where i'm coming from, right?
Nick
Nick2y ago
Context | tRPC
Your context holds data that all of your tRPC procedures will have access to, and is a great place to put things like database connections or authentication information.
Nick
Nick2y ago
I know you've seen this, but here the docs do have a separated function I appreciate it's for Next though, we should change that
Vilian
VilianOP2y ago
Well The example code section did not show how the createContext was attached to the TRPC instance And like i mentioned at the start, it was very confusing to see that the createContext function wasn't used anywhere but in the exported Context infer type, and the fact that the opts parameter was defined as CreateNextContextOptions Anyway, i think i got the info i needed. Regardless of the little pains here and there, i would say that i'm just not used to the library yet. I really do like tRPC and i feel like this is what will power the future of API interfaces. +1 star Thanks for the kind help ❤️
Nick
Nick2y ago
Please do share your thoughts on the RFC, we need this kind of feedback and I agree as I got tripped up in this area too 🙂
Vilian
VilianOP2y ago
By the way, i found this to be a solution to my problem with the type inference of the context function
import type { IncomingMessage, ServerResponse } from 'node:http';
import type { inferAsyncReturnType } from '@trpc/server';
import type { NodeHTTPCreateContextFnOptions } from '@trpc/server/adapters/node-http';


export const createContext = async ({
req,
res
}: NodeHTTPCreateContextFnOptions<IncomingMessage, ServerResponse>) => {
// Stuff...

return {};
};

export type Context = inferAsyncReturnType<typeof createContext>;
import type { IncomingMessage, ServerResponse } from 'node:http';
import type { inferAsyncReturnType } from '@trpc/server';
import type { NodeHTTPCreateContextFnOptions } from '@trpc/server/adapters/node-http';


export const createContext = async ({
req,
res
}: NodeHTTPCreateContextFnOptions<IncomingMessage, ServerResponse>) => {
// Stuff...

return {};
};

export type Context = inferAsyncReturnType<typeof createContext>;