ap0nia / trpc-svelte-toolbox

🔥 tRPC + svelte integrations
https://trpc-svelte-toolbox.vercel.app
9 stars 1 forks source link

Usage without query API, accessing SvelteKit request parameters #7

Open anerli opened 1 month ago

anerli commented 1 month ago

Hi, I had a couple of questions regarding the usage of the library and if a couple things are possible.

(1) Say for some particular situation I want to be able to use the TRPC client to call a procedure but don't want to wrap it in a query, is this easily possible without setting up a separate TRPC client? This may be a stupid question since I am not too familiar with TRPC on its own. (2) I am using SvelteKit, and for pretty much any server procedure I will need to have a couple things that are normally accessible in the context of a sveltekit rest endpoint (e.g. request, locals). Is there a good way to be able to access these within a defined TRPC procedure?

Thanks, library is really cool. If I can figure out how to do these 2 things it will definitely be a killer addition in my codebase.

ap0nia commented 1 month ago

I will have to fact check myself, but I believe that proxy is the property that exposes the typed TRPC client directly. This is based on the code here.

So an example usage would be:

const trpc = createTRPCSvelte(/* ... */)
trpc.proxy.hello.query()

If using SvelteKit and following the documentation's tutorial, it might look something like this:

// src/routes/+page.ts

import type { PageLoad } from './$types'

export const load: PageLoad = (event) => {
  const { trpc } = await event.parent()

  const result = await trpc.proxy.hello.query(event.params.id)

  console.log(result)
}

Let me know if this works or was helpful!

anerli commented 1 month ago

Ok thank you, I think that answers my first question!

Did you have any suggestions for my second question, as to how I could access request variables such as request and locals that you might normally have access to when defining a sveltekit REST endpoint, within a TRPC procedure?

I guess maybe that is more of a TRPC question but not sure.

Thanks for your help so far!

ap0nia commented 1 month ago

Oh, I guess I forgot to document this particular recipe, but any per-request context properties can be set by the createTRPCRequestHandler from my SvelteKit library, @bevm0/trpc-sveltekit. (It's just a light wrapper around the official tRPC fetch adapter with a custom createContext call.

Here's the main points from the kitchen-sink example:

And here's the source code for my SvelteKit adapter if you were curious to know what it does. It's pretty trivial and you could just copy/paste the code if you wanted something custom for your setup.

anerli commented 5 days ago

Thanks that's all very helpful information!

One thing I'm still struggling to do however, is getting type suggestions from my linter on the ctx, or on anything other than input from what it seems.

Basically what I mean is I copied the context.ts example, like this

export const createContext: CreateContext<any, any, any> = (context) => (context)
export type Context = inferAsyncReturnType<typeof createContext>

(I also tried defining a different Context type to see if anything would work, but same result)

but when I define a procedure e.g. .query(async ({ ctx }) => { ... } my linter just says the type of ctx is {}, so I don't get any type hints regardless of what I put in that context. I don't see anything fundamentally different from the setup I have v.s. kitchen sink, should the type be working for ctx with that setup, or is there maybe another approach you're aware of to get that to work?

Thanks again!

anerli commented 5 days ago

Ok I believe I figured out the main cause of my issue, which was just that didn't include the context when initializing TRPC:

const t = initTRPC.context<Context>().create();

Unfortunately this approach didn't work for me to set the Context type it just appeared {}:

export const createContext: CreateContext<any, any, any> = (context) => (context)
export type Context = inferAsyncReturnType<typeof createContext>

So I just defined it manually

export type Context = {
    opts: any,
    event: RequestEvent
}

TBH not totally sure what opts is exactly or where to derive the type - couldn't find much info on it in TRPC docs (maybe you could let me know?) anyway I think that resolves that problem I was having!