Fetch / Edge Runtimes Adapter
Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →
Du kan skapa en tRPC-server i alla edge-runtimes som följer WinterCG, specifikt Minimum Common Web Platform API-specifikationen.
Exempel på sådana runtimes inkluderar, men är inte begränsade till:
-
Cloudflare Workers
-
Deno Deploy
-
Vercel Edge Runtime (& Next.js Edge Runtime)
Detta gör det också enkelt att integrera med ramverk som använder webplatformens API:er för att representera förfrågningar och svar, såsom:
-
Astro (SSR-läge)
-
Remix
-
SolidStart
Exempelappar
| Description | Links |
|---|---|
| Cloudflare Workers example | Source |
| Deno Deploy example | Source |
| Next.js Edge Runtime example | Source |
| Vercel Edge Runtime example | Source |
Så använder du tRPC-server med en edge-runtime
tRPC tillhandahåller en fetch-adapter som använder de inbyggda Request- och Response-API:erna som in- och utdata. tRPC-specifik kod är identisk över alla runtimes, endast sättet att returnera svaret skiljer sig.
tRPC inkluderar en adapter för det inbyggda Fetch API direkt. Denna adapter låter dig konvertera din tRPC-router till en Request-hanterare som returnerar Response-objekt.
Nödvändiga Web API:er
tRPC-servern använder följande Fetch API:er:
-
Request,Response -
fetch -
Headers -
URL
Om din runtime stöder dessa API:er kan du använda tRPC-server.
Kuriosa: det betyder också att du kan köra en tRPC-server direkt i din webbläsare!
Gemensam konfiguration
Installera beroenden
Du kan hoppa över detta steg om du använder Deno Deploy.
- npm
- yarn
- pnpm
- bun
shnpm install @trpc/server zod
shnpm install @trpc/server zod
shyarn add @trpc/server zod
shyarn add @trpc/server zod
shpnpm add @trpc/server zod
shpnpm add @trpc/server zod
shbun add @trpc/server zod
shbun add @trpc/server zod
Zod är inte ett obligatoriskt beroende, men det används i exempelroutern nedan.
Skapa routern
Först och främst behöver du en router för att hantera dina queries, mutationer och prenumerationer.
En exempelrouter visas nedan, spara den i en fil som heter router.ts.
router.ts
router.tstsimport { initTRPC } from '@trpc/server';import { z } from 'zod';import { Context } from './context';type User = {id: string;name: string;bio?: string;};const users: Record<string, User> = {};export const t = initTRPC.context<Context>().create();export const appRouter = t.router({getUserById: t.procedure.input(z.string()).query((opts) => {return users[opts.input]; // input type is string}),createUser: t.procedure// validate input with Zod.input(z.object({name: z.string().min(3),bio: z.string().max(142).optional(),}),).mutation((opts) => {const id = Date.now().toString();const user: User = { id, ...opts.input };users[user.id] = user;return user;}),});// export type definition of APIexport type AppRouter = typeof appRouter;
router.tstsimport { initTRPC } from '@trpc/server';import { z } from 'zod';import { Context } from './context';type User = {id: string;name: string;bio?: string;};const users: Record<string, User> = {};export const t = initTRPC.context<Context>().create();export const appRouter = t.router({getUserById: t.procedure.input(z.string()).query((opts) => {return users[opts.input]; // input type is string}),createUser: t.procedure// validate input with Zod.input(z.object({name: z.string().min(3),bio: z.string().max(142).optional(),}),).mutation((opts) => {const id = Date.now().toString();const user: User = { id, ...opts.input };users[user.id] = user;return user;}),});// export type definition of APIexport type AppRouter = typeof appRouter;
Om din router-fil börjar bli för stor, dela upp den i flera subrouters där varje implementeras i sin egen fil. Slå sedan ihop dem till en enda rot-appRouter.
Skapa contexten
Sedan behöver du en context som skapas för varje förfrågan.
Ett exempel på en context visas nedan, spara den i en fil som heter context.ts:
context.ts
context.tstsimport { FetchCreateContextFnOptions } from '@trpc/server/adapters/fetch';export function createContext({req,resHeaders,}: FetchCreateContextFnOptions) {const user = { name: req.headers.get('username') ?? 'anonymous' };return { req, resHeaders, user };}export type Context = Awaited<ReturnType<typeof createContext>>;
context.tstsimport { FetchCreateContextFnOptions } from '@trpc/server/adapters/fetch';export function createContext({req,resHeaders,}: FetchCreateContextFnOptions) {const user = { name: req.headers.get('username') ?? 'anonymous' };return { req, resHeaders, user };}export type Context = Awaited<ReturnType<typeof createContext>>;
Runtime-specifik konfiguration
Astro
src/pages/trpc/[trpc].tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import type { APIRoute } from 'astro';import { createContext } from '../../server/context';import { appRouter } from '../../server/router';export const all: APIRoute = (opts) => {return fetchRequestHandler({endpoint: '/trpc',req: opts.request,router: appRouter,createContext,});};
src/pages/trpc/[trpc].tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import type { APIRoute } from 'astro';import { createContext } from '../../server/context';import { appRouter } from '../../server/router';export const all: APIRoute = (opts) => {return fetchRequestHandler({endpoint: '/trpc',req: opts.request,router: appRouter,createContext,});};
Cloudflare Worker
Du behöver Wrangler CLI för att köra Cloudflare Workers.
Skapa Cloudflare Worker
server.tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from './context';import { appRouter } from './router';export default {async fetch(request: Request): Promise<Response> {return fetchRequestHandler({endpoint: '/trpc',req: request,router: appRouter,createContext,});},};
server.tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from './context';import { appRouter } from './router';export default {async fetch(request: Request): Promise<Response> {return fetchRequestHandler({endpoint: '/trpc',req: request,router: appRouter,createContext,});},};
Kör wrangler dev server.ts så blir dina endpoints tillgängliga via HTTP!
| Endpoint | HTTP URI |
|---|---|
getUser | GET http://localhost:8787/trpc/getUserById?input=INPUT where INPUT is a URI-encoded JSON string. |
createUser | POST http://localhost:8787/trpc/createUser with req.body of type User |
Deno Oak
Detta förutsätter att du har Deno installerat och konfigurerat. Se deras komma igång-guide för mer information.
Uppdatera importen i router.ts
router.tstsimport { initTRPC } from 'npm:@trpc/server';import { z } from 'npm:zod';import { Context } from './context.ts';
router.tstsimport { initTRPC } from 'npm:@trpc/server';import { z } from 'npm:zod';import { Context } from './context.ts';
Uppdatera importen i context.ts
context.tstsimport { FetchCreateContextFnOptions } from 'npm:@trpc/server/adapters/fetch';
context.tstsimport { FetchCreateContextFnOptions } from 'npm:@trpc/server/adapters/fetch';
Använd fetchRequestHandler med Oak i app.ts
app.tstsimport { Application, Router } from 'https://deno.land/x/oak/mod.ts';import { fetchRequestHandler } from 'npm:@trpc/server/adapters/fetch';import { createContext } from './context.ts';import { appRouter } from './router.ts';const app = new Application();const router = new Router();router.all('/trpc/(.*)', async (ctx) => {const res = await fetchRequestHandler({endpoint: '/trpc',req: new Request(ctx.request.url, {headers: ctx.request.headers,body:ctx.request.method !== 'GET' && ctx.request.method !== 'HEAD'? ctx.request.body({ type: 'stream' }).value: void 0,method: ctx.request.method,}),router: appRouter,createContext,});ctx.response.status = res.status;ctx.response.headers = res.headers;ctx.response.body = res.body;});app.use(router.routes());app.use(router.allowedMethods());await app.listen({ port: 3000 });
app.tstsimport { Application, Router } from 'https://deno.land/x/oak/mod.ts';import { fetchRequestHandler } from 'npm:@trpc/server/adapters/fetch';import { createContext } from './context.ts';import { appRouter } from './router.ts';const app = new Application();const router = new Router();router.all('/trpc/(.*)', async (ctx) => {const res = await fetchRequestHandler({endpoint: '/trpc',req: new Request(ctx.request.url, {headers: ctx.request.headers,body:ctx.request.method !== 'GET' && ctx.request.method !== 'HEAD'? ctx.request.body({ type: 'stream' }).value: void 0,method: ctx.request.method,}),router: appRouter,createContext,});ctx.response.status = res.status;ctx.response.headers = res.headers;ctx.response.body = res.body;});app.use(router.routes());app.use(router.allowedMethods());await app.listen({ port: 3000 });
Deno Deploy
Detta förutsätter att du har Deno installerat och konfigurerat. Se deras komma igång-guide för mer information.
Se vårt exempel på Deno Deploy-app för ett fungerande exempel.
Uppdatera importen i router.ts
router.tstsimport { initTRPC } from 'npm:@trpc/server';import { z } from 'npm:zod';import { Context } from './context.ts';
router.tstsimport { initTRPC } from 'npm:@trpc/server';import { z } from 'npm:zod';import { Context } from './context.ts';
Uppdatera importen i context.ts
context.tstsimport { FetchCreateContextFnOptions } from 'npm:@trpc/server/adapters/fetch';
context.tstsimport { FetchCreateContextFnOptions } from 'npm:@trpc/server/adapters/fetch';
Skapa Deno Deploy-funktion
server.tstsimport { fetchRequestHandler } from 'npm:@trpc/server/adapters/fetch';import { createContext } from './context.ts';import { appRouter } from './router.ts';function handler(request) {return fetchRequestHandler({endpoint: '/trpc',req: request,router: appRouter,createContext,});}Deno.serve(handler);
server.tstsimport { fetchRequestHandler } from 'npm:@trpc/server/adapters/fetch';import { createContext } from './context.ts';import { appRouter } from './router.ts';function handler(request) {return fetchRequestHandler({endpoint: '/trpc',req: request,router: appRouter,createContext,});}Deno.serve(handler);
Kör deno run --allow-net=:8000 --allow-env ./server.ts så blir dina endpoints tillgängliga via HTTP!
| Endpoint | HTTP URI |
|---|---|
getUser | GET http://localhost:8000/trpc/getUserById?input=INPUT where INPUT is a URI-encoded JSON string. |
createUser | POST http://localhost:8000/trpc/createUser with req.body of type User |
Next.js Edge Runtime
Se ett fullständigt exempel här.
Remix
app/routes/trpc/$trpc.tstsimport type { ActionArgs, LoaderArgs } from '@remix-run/node';import { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from '~/server/context';import { appRouter } from '~/server/router';export const loader = async (args: LoaderArgs) => {return handleRequest(args);};export const action = async (args: ActionArgs) => {return handleRequest(args);};function handleRequest(args: LoaderArgs | ActionArgs) {return fetchRequestHandler({endpoint: '/trpc',req: args.request,router: appRouter,createContext,});}
app/routes/trpc/$trpc.tstsimport type { ActionArgs, LoaderArgs } from '@remix-run/node';import { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from '~/server/context';import { appRouter } from '~/server/router';export const loader = async (args: LoaderArgs) => {return handleRequest(args);};export const action = async (args: ActionArgs) => {return handleRequest(args);};function handleRequest(args: LoaderArgs | ActionArgs) {return fetchRequestHandler({endpoint: '/trpc',req: args.request,router: appRouter,createContext,});}
SolidStart
src/routes/api/trpc/[trpc].tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import type { APIEvent } from 'solid-start';import { createContext } from '../../server/context';import { appRouter } from '../../server/router';const handler = (event: APIEvent) =>fetchRequestHandler({endpoint: '/api/trpc',req: event.request,router: appRouter,createContext,});export { handler as GET, handler as POST };
src/routes/api/trpc/[trpc].tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import type { APIEvent } from 'solid-start';import { createContext } from '../../server/context';import { appRouter } from '../../server/router';const handler = (event: APIEvent) =>fetchRequestHandler({endpoint: '/api/trpc',req: event.request,router: appRouter,createContext,});export { handler as GET, handler as POST };
Vercel Edge Runtime
Se den officiella Vercel Edge Runtime-dokumentationen för mer information.
Se vårt exempel på Vercel Edge Runtime-app för ett fungerande exempel.
Installera beroenden
- npm
- yarn
- pnpm
- bun
shnpm install -g edge-runtime
shnpm install -g edge-runtime
shyarn global add edge-runtime
shyarn global add edge-runtime
shpnpm add -g edge-runtime
shpnpm add -g edge-runtime
shbun add -g edge-runtime
shbun add -g edge-runtime
Skapa Edge Runtime-funktion
server.tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from './context';import { appRouter } from './router';addEventListener('fetch', (event) => {return event.respondWith(fetchRequestHandler({endpoint: '/trpc',req: event.request,router: appRouter,createContext,}),);});
server.tstsimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';import { createContext } from './context';import { appRouter } from './router';addEventListener('fetch', (event) => {return event.respondWith(fetchRequestHandler({endpoint: '/trpc',req: event.request,router: appRouter,createContext,}),);});
Kör edge-runtime --listen server.ts --port 3000 så blir dina endpoints tillgängliga via HTTP!
| Endpoint | HTTP URI |
|---|---|
getUser | GET http://localhost:3000/trpc/getUserById?input=INPUT where INPUT is a URI-encoded JSON string. |
createUser | POST http://localhost:3000/trpc/createUser with req.body of type User |