Skip to main content
Version: 11.x

独立适配器

tRPC 的独立适配器是让新项目运行的最简单方法。它非常适合本地开发和基于服务器的生产环境。本质上,它只是标准 Node.js HTTP 服务器 的封装,包含与 tRPC 相关的常规选项。

¥tRPC's Standalone Adapter is the simplest way to get a new project working. It's ideal for local development, and for server-based production environments. In essence it's just a wrapper around the standard Node.js HTTP Server with the normal options related to tRPC.

如果你有现有的 API 部署(例如 ExpressFastifyNext.js),并且想要将 tRPC 集成到其中,则应该查看它们各自的适配器。同样,如果你更喜欢在无服务器或边缘计算上托管,我们有 AWS Lambda拿来 等适配器可能适合你的需求。

¥If you have an existing API deployment like Express, Fastify, or Next.js, which you want to integrate tRPC into, you should have a look at their respective adapters. Likewise if you have a preference to host on serverless or edge compute, we have adapters like AWS Lambda and Fetch which may fit your needs.

当部署的适配器很难在本地计算机上运行时,应用中有 2 个入口点的情况也很常见。你可以使用独立适配器进行本地开发,并在部署时使用不同的适配器。

¥It's also not uncommon, where the deployed adapter is hard to run on local machines, to have 2 entry-points in your application. You could use the Standalone Adapter for local development, and a different adapter when deployed.

示例应用

¥Example app

描述链接
独立 tRPC 服务器
具有 CORS 处理功能的独立 tRPC 服务器

设置独立 tRPC 服务器

¥Setting up a Standalone tRPC Server

1. 实现你的应用路由

¥ Implement your App Router

实现你的 tRPC 路由。例如:

¥Implement your tRPC router. For example:

appRouter.ts
ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
export const t = initTRPC.create();
export const appRouter = t.router({
getUser: t.procedure.input(z.string()).query((opts) => {
return { id: opts.input, name: 'Bilbo' };
}),
createUser: t.procedure
.input(z.object({ name: z.string().min(5) }))
.mutation(async (opts) => {
// use your ORM of choice
return await UserModel.create({
data: opts.input,
});
}),
});
// export type definition of API
export type AppRouter = typeof appRouter;
appRouter.ts
ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
export const t = initTRPC.create();
export const appRouter = t.router({
getUser: t.procedure.input(z.string()).query((opts) => {
return { id: opts.input, name: 'Bilbo' };
}),
createUser: t.procedure
.input(z.object({ name: z.string().min(5) }))
.mutation(async (opts) => {
// use your ORM of choice
return await UserModel.create({
data: opts.input,
});
}),
});
// export type definition of API
export type AppRouter = typeof appRouter;

欲了解更多信息,你可以查看 快速入门指南

¥For more information you can look at the quickstart guide

2. 使用独立适配器

¥ Use the Standalone adapter

独立适配器运行一个简单的 Node.js HTTP 服务器。

¥The Standalone adapter runs a simple Node.js HTTP server.

server.ts
ts
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './appRouter.ts';
createHTTPServer({
router: appRouter,
createContext() {
console.log('context 3');
return {};
},
// basePath: '/trpc/', // optional, defaults to '/'
}).listen(2022);
server.ts
ts
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './appRouter.ts';
createHTTPServer({
router: appRouter,
createContext() {
console.log('context 3');
return {};
},
// basePath: '/trpc/', // optional, defaults to '/'
}).listen(2022);

处理 CORS 和选项

¥Handling CORS & OPTIONS

默认情况下,独立服务器不会响应 HTTP OPTIONS 请求,也不会设置任何 CORS 标头。

¥By default the standalone server will not respond to HTTP OPTIONS requests, or set any CORS headers.

如果你没有托管在可以为你处理此问题的环境中(例如在本地开发期间),你可能需要处理它。

¥If you're not hosting in an environment which can handle this for you, like during local development, you may need to handle it.

1. 安装 cors

¥ Install cors

你可以使用流行的 cors 包自行添加支持

¥You can add support yourself with the popular cors package

bash
yarn add cors
yarn add -D @types/cors
bash
yarn add cors
yarn add -D @types/cors

有关如何配置此包的完整信息,检查文档

¥For full information on how to configure this package, check the docs

2. 配置独立服务器

¥ Configure the Standalone server

此示例只是向任何请求抛出开放的 CORS,这对于开发很有用,但你可以而且应该在生产环境中更严格地配置它。

¥This example just throws open CORS to any request, which is useful for development, but you can and should configure it more strictly in a production environment.

server.ts
ts
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import cors from 'cors';
createHTTPServer({
middleware: cors(),
router: appRouter,
createContext() {
console.log('context 3');
return {};
},
}).listen(3333);
server.ts
ts
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import cors from 'cors';
createHTTPServer({
middleware: cors(),
router: appRouter,
createContext() {
console.log('context 3');
return {};
},
}).listen(3333);

middleware 选项将接受任何类似于 connect/node.js 中间件的函数,因此如果你愿意,它可以用于 cors 以外的处理。然而,它的目的是作为一个简单的应急方案,因此它本身不允许你将多个中间件组合在一起。如果你想这样做,那么你可以:

¥The middleware option will accept any function which resembles a connect/node.js middleware, so it can be used for more than cors handling if you wish. It is, however, intended to be a simple escape hatch and as such won't on its own allow you to compose multiple middlewares together. If you want to do this then you could:

  1. 使用具有更全面的中间件支持的备用适配器,例如 快速适配器

    ¥Use an alternate adapter with more comprehensive middleware support, like the Express adapter

  2. 使用解决方案来编写中间件,例如 connect

    ¥Use a solution to compose middlewares such as connect

  3. 使用自定义 http 服务器扩展独立 createHTTPHandler(见下文)

    ¥Extend the Standalone createHTTPHandler with a custom http server (see below)

向自定义 HTTP 服务器添加处理程序

¥Adding a handler to an Custom HTTP server

createHTTPServer 返回 Node 内置 http.Serverhttps://nodejs.cn/api/http.html#class-httpserver)的一个实例,这意味着你可以访问它的所有属性和 API。但是,如果 createHTTPServer 不足以满足你的用例,你还可以使用独立适配器的 createHTTPHandler 功能来创建自己的 HTTP 服务器。例如:

¥createHTTPServer is returning an instance of Node's built-in http.Server(https://nodejs.cn/api/http.html#class-httpserver), which means that you have an access to all it's properties and APIs. However, if createHTTPServer isn't enough for your usecase, you can also use the standalone adapter's createHTTPHandler function to create your own HTTP server. For instance:

server.ts
ts
import { createServer } from 'http';
import { initTRPC } from '@trpc/server';
import { createHTTPHandler } from '@trpc/server/adapters/standalone';
const handler = createHTTPHandler({
router: appRouter,
createContext() {
return {};
},
});
createServer((req, res) => {
/**
* Handle the request however you like,
* just call the tRPC handler when you're ready
*/
handler(req, res);
}).listen(3001);
server.ts
ts
import { createServer } from 'http';
import { initTRPC } from '@trpc/server';
import { createHTTPHandler } from '@trpc/server/adapters/standalone';
const handler = createHTTPHandler({
router: appRouter,
createContext() {
return {};
},
});
createServer((req, res) => {
/**
* Handle the request however you like,
* just call the tRPC handler when you're ready
*/
handler(req, res);
}).listen(3001);

自定义处理请求的基本路径下

¥Custom base path to handle requests under

独立适配器还支持 basePath 选项,它将从请求路径的开头切分 basePath。

¥The Standalone adapter also supports a basePath option, which will slice the basePath from the beginning of the request path.

server.ts
ts
import { createServer } from 'http';
import { initTRPC } from '@trpc/server';
import { createHTTPHandler } from '@trpc/server/adapters/standalone';
const handler = createHTTPHandler({
router: appRouter,
basePath: '/trpc/',
});
createServer((req, res) => {
if (req.url?.startsWith('/trpc/')) {
return handler(req, res);
}
// [... insert your custom logic here ...]
res.statusCode = 404;
res.end('Not Found');
}).listen(3001);
server.ts
ts
import { createServer } from 'http';
import { initTRPC } from '@trpc/server';
import { createHTTPHandler } from '@trpc/server/adapters/standalone';
const handler = createHTTPHandler({
router: appRouter,
basePath: '/trpc/',
});
createServer((req, res) => {
if (req.url?.startsWith('/trpc/')) {
return handler(req, res);
}
// [... insert your custom logic here ...]
res.statusCode = 404;
res.end('Not Found');
}).listen(3001);

HTTP2

独立适配器还支持 HTTP/2。

¥The Standalone adapter also supports HTTP/2.

server.ts
ts
import http2 from 'http2';
import { createHTTP2Handler } from '@trpc/server/adapters/standalone';
import { appRouter } from './_app.ts';
import { createContext } from './context.ts';
const handler = createHTTP2Handler({
router: appRouter,
createContext,
// basePath: '/trpc/', // optional, defaults to '/'
});
const server = http2.createSecureServer(
{
key: '...',
cert: '...',
},
(req, res) => {
/**
* Handle the request however you like,
* just call the tRPC handler when you're ready
*/
handler(req, res);
},
);
server.listen(3001);
server.ts
ts
import http2 from 'http2';
import { createHTTP2Handler } from '@trpc/server/adapters/standalone';
import { appRouter } from './_app.ts';
import { createContext } from './context.ts';
const handler = createHTTP2Handler({
router: appRouter,
createContext,
// basePath: '/trpc/', // optional, defaults to '/'
});
const server = http2.createSecureServer(
{
key: '...',
cert: '...',
},
(req, res) => {
/**
* Handle the request however you like,
* just call the tRPC handler when you're ready
*/
handler(req, res);
},
);
server.listen(3001);
context.ts
ts
import { CreateHTTP2ContextOptions } from '@trpc/server/adapters/standalone';
 
export async function createContext(opts: CreateHTTP2ContextOptions) {
opts.req;
(property) req: http2.Http2ServerRequest
opts.res;
(property) res: http2.Http2ServerResponse
 
opts.info;
(property) info: TRPCRequestInfo
return {};
}
 
export type Context = Awaited<ReturnType<typeof createContext>>;
context.ts
ts
import { CreateHTTP2ContextOptions } from '@trpc/server/adapters/standalone';
 
export async function createContext(opts: CreateHTTP2ContextOptions) {
opts.req;
(property) req: http2.Http2ServerRequest
opts.res;
(property) res: http2.Http2ServerResponse
 
opts.info;
(property) info: TRPCRequestInfo
return {};
}
 
export type Context = Awaited<ReturnType<typeof createContext>>;