Tuxer
Tuxer15mo ago

How to pass context to vanilla client?

Hi, I have a next app where I use trpc. Now I need to call some trpc functions from outside of any components. My first solution was to just call the endpoint with axios. const { data: attribute } = await axios({ method: "GET", url: getApiServerUrl() + "/trpc/db.getAttribute", params: { input: JSON.stringify(trpcInput) }, headers: { 'Cookie': cookie } }); This is working fine, but I lose typing support. My new solution is to use the vanilla client. But using the vanilla client I can't find a way to pass context to the request, for example to pass a cookie. Now my walkaround is creating a getter function that each time creates a new trpc client with the context needed. export const getClientWithCookie = ({cookie}: {cookie: string}) => createTRPCProxyClient<AppRouter>({ links: [ httpBatchLink({ url: getApiServerUrl() + /trpc, headers() { return { cookie: cookie, }; }, }), ], }); const attribute = await getClientWithCookie({cookie: cookie}).db.getAttribute.query(trpcInput); This is also working fine, but feels a bit hacky to me, because each time it creates a new client. How would be the proper solution to call a trpc function with context like a cookie using the vanilla client? (I can't use hooks here)
16 Replies
APEX
APEX6mo ago
I want to revive this because I searched through #❓-help and didn't find any other post answering this. If your server sets Set-Cookie, how do you retrieve that cookie in the Vanilla tRPC client?
APEX
APEX6mo ago
From Node.JS clientside I call my login proc, which gives me back a user ID and gives me a session token via Set-Cookie, but I cannot for the life of me figure out how to get that cookie. I've been digging through the docs and the code for hours now.
No description
APEX
APEX6mo ago
I think my issue is actually not quite related to OP's issue but you'll forgive me since I have been staring at my screen too long
BeBoRE
BeBoRE6mo ago
Cookies are managed by the browser and are sent on subsequent requests to the server, you don’t have to include it yourself Only when using SSR do you have to pass the cookies to the link
APEX
APEX6mo ago
This is NodeJS, not the browser Node AFAIK does not store the cookie, subsequent requests are met with auth errors
Jimmy
Jimmy5mo ago
If the node server sets Set-Cookie, the browser will automatically add the cookie to the req header on each http calls. I think your question is that your trpc client can't access the req header or the http-only cookies. So my suggestion is that handle the auth event(like validate cookies) through the node middleware, and set something you want to the ctx(like req.trpc.session or ctx.trpc.session), then pass them to trpc context. Make sure the trpc middleware should run after the auth middleware.
APEX
APEX5mo ago
Again, there is no browser involved here. I am running the vanilla client in NodeJS.
Jimmy
Jimmy5mo ago
Since the Node.js will not handle the Set-Cookie automatically, you should parse the header and save the token manually in the server adapter.
APEX
APEX5mo ago
Okay, how do I actually get the header? Can I write middleware for the client?
Jimmy
Jimmy5mo ago
I think you could write a middleware after the trpc adapter, if the res.headers include Set-Cookie it parses the header and saves the cookie somewhere(could be stored at the top level variable I think), and you also need to write another middleware before the trpc adapter, it writes the cookie to the req.headers if the cookie is not null.
APEX
APEX5mo ago
Ok, I think my issue here then is documentation. I understand that you can write middleware for the server by calling .use on a procedure, but I don't see anything about doing this on the client. The solution I'm using as of yesterday is to use fetch to call the login API and save the cookie to a variable, then use the headers function of the object I pass to httpBatchLink to set that cookie in subsequent requests' headers (using tRPC for subsequent requests).
Jimmy
Jimmy5mo ago
Hmmm, the middleware I said is the server side not the trpc's.
APEX
APEX5mo ago
I think there has to be a miscommunication somewhere lol Maybe it would be helpful to know that I cannot modify the server? It is running on a website I don't manage. I'm writing a third party API client, I am forced to deal with the Set-Cookie header. There is a server running NodeJS+tRPC. I am trying to write a different NodeJS package, also using tRPC, for making programmatic API calls to that server. The API server does session tracking using Set-Cookie. The API client, since it is also NodeJS, does not respect the Set-Cookie header (as far as I am aware), so I have to access the header myself to store the cookie in a variable somewhere. My issue is that I cannot figure out how to directly access the request header using @trpc/client. I am aware that this is probably an uncommon and unsupported use case (specifically the part about this being a 3rd party client), but I still think it highlights either a feature missing from the vanilla client, or, if the feature does exist, it highlights missing documentation for it
Jimmy
Jimmy5mo ago
HTTP Batch Link | tRPC
httpBatchLink is a terminating link that batches an array of individual tRPC operations into a single HTTP request that's sent to a single tRPC procedure.
APEX
APEX5mo ago
Yes, I'm using this already. I mention it here Maybe I can supply a custom fetch() that detects set-cookie in the response? That feels very hacky Yeah ok that works, it's not really much better than the other solution but at least it consolidates all my API calls to only using tRPC.
Jimmy
Jimmy5mo ago
I think this is the best way now. 😫 To rewrite the fetch() function