メインコンテンツへスキップ
バージョン: 9.x

HTTP RPC仕様

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

メソッドと型の対応関係

HTTP MethodMappingNotes
GET.query()Input JSON-stringified in query param.
e.g. myQuery?input=${encodeURIComponent(JSON.stringify(input))
POST.mutation()Input as POST body.
n/a.subscription()Subscriptions are not supported in HTTP transport

バッチ処理

バッチ処理時には、同じタイプの並列プロシージャ呼び出しをすべて、データローダーを使用して1つのリクエストにまとめます。

  • 呼び出されるプロシージャ名はpathnameでカンマ(,)区切りで結合されます

  • 入力パラメータはinputというクエリパラメータとして送信され、その形式はRecord<number, unknown>です

  • クエリパラメータとしてbatch=1も渡す必要があります

  • レスポンスに異なるステータスが含まれる場合、207 Multi-Statusを返します(例: 1つの呼び出しがエラーになり、もう1つが成功した場合)

バッチ処理のリクエスト例

/api/trpcで公開されている次のようなルーターがある場合:

server/router.ts
tsx
export const appRouter = trpc
.router<Context>()
.query('postById', {
input: String,
async resolve({ input, ctx }) {
const post = await ctx.post.findUnique({
where: { id: input },
});
return post;
},
})
.query('relatedPosts', {
input: String,
async resolve({ ctx, input }) {
const posts = await ctx.findRelatedPostsById(input);
return posts;
},
});
server/router.ts
tsx
export const appRouter = trpc
.router<Context>()
.query('postById', {
input: String,
async resolve({ input, ctx }) {
const post = await ctx.post.findUnique({
where: { id: input },
});
return post;
},
})
.query('relatedPosts', {
input: String,
async resolve({ ctx, input }) {
const posts = await ctx.findRelatedPostsById(input);
return posts;
},
});

そして、Reactコンポーネント内で次のように定義された2つのクエリ:

MyComponent.tsx
tsx
export function MyComponent() {
const post1 = trpc.useQuery(['postById', '1']);
const relatedPosts = trpc.useQuery(['relatedPosts', '1']);
return (
<pre>
{JSON.stringify(
{
post1: post1.data ?? null,
relatedPosts: relatedPosts.data ?? null,
},
null,
4,
)}
</pre>
);
}
MyComponent.tsx
tsx
export function MyComponent() {
const post1 = trpc.useQuery(['postById', '1']);
const relatedPosts = trpc.useQuery(['relatedPosts', '1']);
return (
<pre>
{JSON.stringify(
{
post1: post1.data ?? null,
relatedPosts: relatedPosts.data ?? null,
},
null,
4,
)}
</pre>
);
}

上記は次のデータを持つ正確に1回のHTTP呼び出しを生成します:

Location propertyValue
pathname/api/trpc/postById,relatedPosts
search?batch=1&input=%7B%220%22%3A%221%22%2C%221%22%3A%221%22%7D *

*) 上記のinputは次の処理結果です:

ts
encodeURIComponent(
JSON.stringify({
0: '1', // <-- input for `postById`
1: '1', // <-- input for `relatedPosts`
}),
);
ts
encodeURIComponent(
JSON.stringify({
0: '1', // <-- input for `postById`
1: '1', // <-- input for `relatedPosts`
}),
);

バッチ処理のレスポンス例

Example output from server
json
[
// result for `postById`
{
"id": null,
"result": {
"type": "data",
"data": {
"id": "1",
"title": "Hello tRPC",
"body": "..."
// ...
}
}
},
// result for `relatedPosts`
{
"id": null,
"result": {
"type": "data",
"data": [
/* ... */
]
}
}
]
json
[
// result for `postById`
{
"id": null,
"result": {
"type": "data",
"data": {
"id": "1",
"title": "Hello tRPC",
"body": "..."
// ...
}
}
},
// result for `relatedPosts`
{
"id": null,
"result": {
"type": "data",
"data": [
/* ... */
]
}
}
]

HTTPレスポンス仕様

トランスポート層に依存しない仕様を実現するため、可能な限りJSON-RPC 2.0に準拠します。

成功レスポンス

Example JSON Response
json
{
"id": null,
"result": {
"type": "data",
"data": {
"id": "1",
"title": "Hello tRPC",
"body": "..."
}
}
}
json
{
"id": null,
"result": {
"type": "data",
"data": {
"id": "1",
"title": "Hello tRPC",
"body": "..."
}
}
}
ts
{
id: null;
result: {
type: 'data';
data: TOutput; // output from procedure
}
}
ts
{
id: null;
result: {
type: 'data';
data: TOutput; // output from procedure
}
}

エラーレスポンス

Example JSON Response
json
[
{
"id": null,
"error": {
"json": {
"message": "Something went wrong",
"code": -32600, // JSON-RPC 2.0 code
"data": {
// Extra, customizable, meta data
"code": "INTERNAL_SERVER_ERROR",
"httpStatus": 500,
"stack": "...",
"path": "post.add"
}
}
}
}
]
json
[
{
"id": null,
"error": {
"json": {
"message": "Something went wrong",
"code": -32600, // JSON-RPC 2.0 code
"data": {
// Extra, customizable, meta data
"code": "INTERNAL_SERVER_ERROR",
"httpStatus": 500,
"stack": "...",
"path": "post.add"
}
}
}
}
]

  • 可能な場合、スローされたエラーからHTTPステータスコードを伝播します

  • レスポンスに異なるステータスが含まれる場合、207 Multi-Statusを返します(例: 1つの呼び出しがエラーになり、もう1つが成功した場合)

  • エラーとそのカスタマイズ方法の詳細については、エラーフォーマットを参照してください。

エラーコードとHTTPステータスの対応

ts
PARSE_ERROR: 400,
BAD_REQUEST: 400,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
TIMEOUT: 408,
CONFLICT: 409,
CLIENT_CLOSED_REQUEST: 499,
PRECONDITION_FAILED: 412,
PAYLOAD_TOO_LARGE: 413,
METHOD_NOT_SUPPORTED: 405,
ts
PARSE_ERROR: 400,
BAD_REQUEST: 400,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
TIMEOUT: 408,
CONFLICT: 409,
CLIENT_CLOSED_REQUEST: 499,
PRECONDITION_FAILED: 412,
PAYLOAD_TOO_LARGE: 413,
METHOD_NOT_SUPPORTED: 405,

エラーコードとJSON-RPC 2.0エラーコードの対応

Available codes & JSON-RPC code
ts
/**
* JSON-RPC 2.0 Error codes
*
* `-32000` to `-32099` are reserved for implementation-defined server-errors.
* For tRPC we're copying the last digits of HTTP 4XX errors.
*/
export const TRPC_ERROR_CODES_BY_KEY = {
/**
* Invalid JSON was received by the server.
* An error occurred on the server while parsing the JSON text.
*/
PARSE_ERROR: -32700,
/**
* The JSON sent is not a valid Request object.
*/
BAD_REQUEST: -32600, // 400
/**
* Internal JSON-RPC error.
*/
INTERNAL_SERVER_ERROR: -32603,
// Implementation specific errors
UNAUTHORIZED: -32001, // 401
FORBIDDEN: -32003, // 403
NOT_FOUND: -32004, // 404
METHOD_NOT_SUPPORTED: -32005, // 405
TIMEOUT: -32008, // 408
CONFLICT: -32009, // 409
PRECONDITION_FAILED: -32012, // 412
PAYLOAD_TOO_LARGE: -32013, // 413
CLIENT_CLOSED_REQUEST: -32099, // 499
} as const;
ts
/**
* JSON-RPC 2.0 Error codes
*
* `-32000` to `-32099` are reserved for implementation-defined server-errors.
* For tRPC we're copying the last digits of HTTP 4XX errors.
*/
export const TRPC_ERROR_CODES_BY_KEY = {
/**
* Invalid JSON was received by the server.
* An error occurred on the server while parsing the JSON text.
*/
PARSE_ERROR: -32700,
/**
* The JSON sent is not a valid Request object.
*/
BAD_REQUEST: -32600, // 400
/**
* Internal JSON-RPC error.
*/
INTERNAL_SERVER_ERROR: -32603,
// Implementation specific errors
UNAUTHORIZED: -32001, // 401
FORBIDDEN: -32003, // 403
NOT_FOUND: -32004, // 404
METHOD_NOT_SUPPORTED: -32005, // 405
TIMEOUT: -32008, // 408
CONFLICT: -32009, // 409
PRECONDITION_FAILED: -32012, // 412
PAYLOAD_TOO_LARGE: -32013, // 413
CLIENT_CLOSED_REQUEST: -32099, // 499
} as const;

詳細を探る

TypeScriptの型定義を深く掘り下げることで、さらなる詳細を確認できます: