vishalbalaji / trpc-svelte-query-adapter

A simple adapter to use `@tanstack/svelte-query` with trpc, similar to `@trpc/react-query`.
71 stars 6 forks source link

Loading trpc in +page.server #41

Closed cellulosa closed 3 months ago

cellulosa commented 3 months ago

heya thanks for the lib.

Am I right thinking that if I want to use trpc on a server code, I need an entirely different isntance?

eg.

// $lib/trpc.ts

import type { AppRouter } from '$lib/server/trpc/routes';
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import SuperJSON from 'superjson';
import { svelteQueryWrapper } from 'trpc-svelte-query-adapter';
import type { QueryClient } from '@tanstack/svelte-query';

const client = createTRPCProxyClient<AppRouter>({
    links: [
        httpBatchLink({
            url: 'http://localhost:5173/api/trpc'
        })
    ],
    transformer: SuperJSON
});

export const trpc = (queryClient?: QueryClient) =>
    svelteQueryWrapper<AppRouter>({
        client,
        queryClient
    });

export const trpcOnServer = (fetch) =>
    createTRPCProxyClient<AppRouter>({
        links: [
            httpBatchLink({
                url: '/api/trpc',
                fetch
            })
        ],
        transformer: SuperJSON
    });
// +page.server.ts

import type { Actions } from './$types';
import { trpcOnServer } from '$lib/trpc';

export const actions: Actions = {
    default: async ({ request, fetch }) => {
        const data = await request.formData();
        const email = data.get('email');

        const api = trpcOnServer(fetch);

        const [newProject] = await api.projects.save.mutate({
                email
        });
    }
};
vishalbalaji commented 3 months ago

Hey @cellulosa,

Tanstack Query and subsequently tRPC's client are mainly meant to handle client-side calls and logic. For server side calls, since you won't need to handle things like loading state or re-fetching, you might want to just create a tRPC caller, like in this example: https://trpc.io/docs/server/server-side-calls

Hope that this helps. Please mark the issue as completed if it does.

cellulosa commented 3 months ago

My issue is understanding how to set the context 🤔 altohugh is server-side calls, I still need to relate the call to the user to make sure I run through authorisations etc

vishalbalaji commented 3 months ago

The docs I share above have an example showing how you can use the context while creating a caller.

https://trpc.io/docs/server/server-side-calls#example-usage-in-an-integration-test

Basically, you just call the createContext function you have created to get a context and pass that to the server caller while initializing.

cellulosa commented 3 months ago

LMAO apologies, it wasn't working simply because I hadn't committed the change on the database, hence Ithe rseult was undefined 😅

for anybody else interested, I simply followed the linked instructions and set the context with:

// +page.server.ts
import { createContext } from '$lib/server/trpc/context';
import { createCaller } from '$lib/server/trpc/caller';

export const actions: Actions = {
    default: async (event) => {
        const ctx = await createContext(event);
        const caller = createCaller(ctx);
        const results = await caller.users.list();
...
// $lib/server/trpc/context
import type { RequestEvent } from '@sveltejs/kit';
import type { inferAsyncReturnType } from '@trpc/server';

export const createContext = async (event: RequestEvent) => ({ event });
export type Context = inferAsyncReturnType<typeof createContext>;
// $lib/server/trpc/caller
import { createCallerFactory } from '$lib/server/trpc';
import { appRouter } from '$lib/server/trpc/routes';

export const createCaller = createCallerFactory(appRouter);