スタンドアロンアダプター
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
tRPCのスタンドアロンアダプターは、新規プロジェクトを最も簡単に動作させる方法です。ローカル開発やサーバーベースの本番環境に最適です。本質的には標準のNode.js HTTP Serverをラップしたもので、tRPC関連の標準オプションを備えています。
既存のExpress、Fastify、Next.jsなどのAPIデプロイメントにtRPCを統合したい場合は、それぞれのアダプターを参照してください。同様にサーバーレスやエッジコンピュート環境でのホスティングを希望する場合、AWS LambdaやFetchなどニーズに合うアダプターも用意されています。
デプロイ先のアダプターがローカルマシンで実行しづらい場合、アプリケーションに2つのエントリーポイントを設けるのも一般的です。ローカル開発にはスタンドアロンアダプターを、デプロイ時には別のアダプターを使用する方法が考えられます。
サンプルアプリケーション
| Description | Links |
|---|---|
| Standalone tRPC Server | |
| Standalone tRPC Server with CORS handling |
スタンドアロンtRPCサーバーのセットアップ
1. アプリケーションルーターの実装
tRPCルーターを実装します。例:
appRouter.tstsimport { 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 choicereturn await UserModel.create({data: opts.input,});}),});// export type definition of APIexport type AppRouter = typeof appRouter;
appRouter.tstsimport { 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 choicereturn await UserModel.create({data: opts.input,});}),});// export type definition of APIexport type AppRouter = typeof appRouter;
詳細についてはクイックスタートガイドを参照してください
2. スタンドアロンアダプターの使用
スタンドアロンアダプターはシンプルなNode.js HTTPサーバーを実行します。
server.tstsimport { 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.tstsimport { 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 & OPTIONSの処理
デフォルトでは、スタンドアロンサーバーはHTTP OPTIONSリクエストに応答せず、CORSヘッダーも設定しません。
ローカル開発時のように、この処理を代行してくれる環境でホスティングしていない場合は、自身で対応する必要があります。
1. corsのインストール
一般的なcorsパッケージを使用してサポートを追加できます
bashyarn add corsyarn add -D @types/cors
bashyarn add corsyarn add -D @types/cors
設定方法の詳細については公式ドキュメントを参照してください
2. スタンドアロンサーバーの設定
この例では開発に便利なようCORSを全開放していますが、本番環境ではより厳格に設定すべきです。
server.tstsimport { 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.tstsimport { 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処理以外にも使用できます。ただしこれはあくまでシンプルな回避策として設計されているため、単体では複数のミドルウェアを組み合わせられません。これを実現するには次の方法があります:
-
Expressアダプターなど、より包括的なミドルウェアサポートを備えた代替アダプターを使用する
-
connectのようなミドルウェア合成ソリューションを利用する
-
カスタムHTTPサーバーでスタンドアロンの
createHTTPHandlerを拡張する(下記参照)
カスタムHTTPサーバーへのハンドラー追加
createHTTPServerはNode組み込みのhttp.Server (https://nodejs.org/api/http.html#class-httpserver) インスタンスを返すため、すべてのプロパティとAPIにアクセスできます。ただしcreateHTTPServerが要件を満たさない場合、スタンドアロンアダプターのcreateHTTPHandler関数を使用して独自のHTTPサーバーを構築することも可能です。例:
server.tstsimport { 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.tstsimport { 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);
リクエスト処理用カスタムベースパス
スタンドアロンアダプターはbasePathオプションもサポートしており、リクエストパスの先頭からベースパスを切り取ります。
server.tstsimport { 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.tstsimport { 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);
HTTP/2対応
スタンドアロンアダプターはHTTP/2もサポートしています。
server.tstsimport 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.tstsimport 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.tstsimport {CreateHTTP2ContextOptions } from '@trpc/server/adapters/standalone';export async functioncreateContext (opts :CreateHTTP2ContextOptions ) {opts .req ;opts .res ;opts .info ;return {};}export typeContext =Awaited <ReturnType <typeofcreateContext >>;
context.tstsimport {CreateHTTP2ContextOptions } from '@trpc/server/adapters/standalone';export async functioncreateContext (opts :CreateHTTP2ContextOptions ) {opts .req ;opts .res ;opts .info ;return {};}export typeContext =Awaited <ReturnType <typeofcreateContext >>;