HTTP RPC 사양
메서드 <-> 타입 매핑
| HTTP 메서드 | 매핑 | 참고사항 |
|---|---|---|
GET | .query() | 쿼리 매개변수에 입력을 JSON 문자열로 인코딩합니다. 예: myQuery?input=${encodeURIComponent(JSON.stringify(input))} |
POST | .mutation() | 입력을 POST 본문으로 전송합니다. |
GET | .subscription() | 구독은 httpSubscriptionLink를 사용하는 서버 전송 이벤트 또는 wsLink를 사용하는 WebSocket을 통해 지원됩니다. |
중첩 프로시저에 액세스
중첩 프로시저는 마침표로 구분되므로, 아래에서 byId에 대한 요청은 /api/trpc/post.byId에 대한 요청으로 처리됩니다.
tsexport constappRouter =router ({post :router ({byId :publicProcedure .input (String ).query (async (opts ) => {// [...]}),}),});
tsexport constappRouter =router ({post :router ({byId :publicProcedure .input (String ).query (async (opts ) => {// [...]}),}),});
배치 처리
배치 처리 시, 데이터 로더를 사용하여 동일한 HTTP 메서드를 사용하는 모든 병렬 프로시저 호출을 하나의 요청으로 결합합니다.
- 호출된 프로시저 이름은
pathname에서 쉼표(,)로 결합됩니다. - 입력 매개변수는
Record<number, unknown>형식을 가진input이라는 이름의 쿼리 매개변수로 전송됩니다. - 또한
batch=1을 쿼리 매개변수로 전달해야 합니다. - 응답의 상태가 서로 다른 경우,
207 Multi-Status를 반환합니다. (예: 한 호출이 오류가 발생하고 다른 호출이 성공한 경우)
배치 처리 예제 요청
/api/trpc에 노출된 다음과 같은 라우터가 있다고 가정하면:
server/router.tstsxexport constappRouter =t .router ({postById :t .procedure .input (String ).query (async (opts ) => {constpost = awaitopts .ctx .post .findUnique ({where : {id :opts .input },});returnpost ;}),relatedPosts :t .procedure .input (String ).query (async (opts ) => {constposts = awaitopts .ctx .findRelatedPostsById (opts .input );returnposts ;}),});
server/router.tstsxexport constappRouter =t .router ({postById :t .procedure .input (String ).query (async (opts ) => {constpost = awaitopts .ctx .post .findUnique ({where : {id :opts .input },});returnpost ;}),relatedPosts :t .procedure .input (String ).query (async (opts ) => {constposts = awaitopts .ctx .findRelatedPostsById (opts .input );returnposts ;}),});
... 그리고 React 컴포넌트에서 다음과 같이 두 개의 쿼리가 정의되어 있다고 가정하면:
MyComponent.tsxtsxexport functionMyComponent () {constpost1 =trpc .postById .useQuery ('1');constrelatedPosts =trpc .relatedPosts .useQuery ('1');return (<pre >{JSON .stringify ({post1 :post1 .data ?? null,relatedPosts :relatedPosts .data ?? null,},null,4,)}</pre >);}
MyComponent.tsxtsxexport functionMyComponent () {constpost1 =trpc .postById .useQuery ('1');constrelatedPosts =trpc .relatedPosts .useQuery ('1');return (<pre >{JSON .stringify ({post1 :post1 .data ?? null,relatedPosts :relatedPosts .data ?? null,},null,4,)}</pre >);}
위 내용은 다음 데이터를 가진 정확히 1개의 HTTP 호출로 이어집니다:
| 위치 속성 | 값 |
|---|---|
pathname | /api/trpc/postById,relatedPosts |
search | ?batch=1&input=%7B%220%22%3A%221%22%2C%221%22%3A%221%22%7D * |
*) 위의 input은 다음 결과입니다:
tsencodeURIComponent (JSON .stringify ({0: '1', // <-- input for `postById`1: '1', // <-- input for `relatedPosts`}),);
tsencodeURIComponent (JSON .stringify ({0: '1', // <-- input for `postById`1: '1', // <-- input for `relatedPosts`}),);
배치 처리 예제 응답
서버에서 반환된 예제 출력
json[// result for `postById`{"result": {"data": {"id": "1","title": "Hello tRPC","body": "..."// ...}}},// result for `relatedPosts`{"result": {"data": [/* ... */]}}]
json[// result for `postById`{"result": {"data": {"id": "1","title": "Hello tRPC","body": "..."// ...}}},// result for `relatedPosts`{"result": {"data": [/* ... */]}}]
HTTP 응답 사양
트랜스포트 계층에 관계없이 작동하는 사양을 갖추기 위해 가능한 한 JSON-RPC 2.0에 따르도록 노력합니다.
성공 응답
예제 JSON 응답
json{"result": {"data": {"id": "1","title": "Hello tRPC","body": "..."}}}
json{"result": {"data": {"id": "1","title": "Hello tRPC","body": "..."}}}
tsinterfaceSuccessResponse {result : {data :TOutput ; // output from procedure}}
tsinterfaceSuccessResponse {result : {data :TOutput ; // output from procedure}}
오류 응답
예제 JSON 응답
json[{"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[{"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"}}}}]
- 가능한 경우, throw된 오류에서 HTTP 상태 코드를 전파합니다.
- 응답의 상태가 서로 다른 경우,
207 Multi-Status를 반환합니다. (예: 한 호출이 오류가 발생하고 다른 호출이 성공한 경우) - 오류 및 커스터마이징 방법에 대한 자세한 내용은 Error Formatting을 참조하세요.
오류 코드 <-> HTTP 상태
tsconstHTTP_STATUS_CODES = {PARSE_ERROR : 400,BAD_REQUEST : 400,UNAUTHORIZED : 401,PAYMENT_REQUIRED : 402,FORBIDDEN : 403,NOT_FOUND : 404,METHOD_NOT_SUPPORTED : 405,TIMEOUT : 408,CONFLICT : 409,PRECONDITION_FAILED : 412,PAYLOAD_TOO_LARGE : 413,UNSUPPORTED_MEDIA_TYPE : 415,UNPROCESSABLE_CONTENT : 422,PRECONDITION_REQUIRED : 428,TOO_MANY_REQUESTS : 429,CLIENT_CLOSED_REQUEST : 499,INTERNAL_SERVER_ERROR : 500,NOT_IMPLEMENTED : 501,BAD_GATEWAY : 502,SERVICE_UNAVAILABLE : 503,GATEWAY_TIMEOUT : 504,} asconst ;
tsconstHTTP_STATUS_CODES = {PARSE_ERROR : 400,BAD_REQUEST : 400,UNAUTHORIZED : 401,PAYMENT_REQUIRED : 402,FORBIDDEN : 403,NOT_FOUND : 404,METHOD_NOT_SUPPORTED : 405,TIMEOUT : 408,CONFLICT : 409,PRECONDITION_FAILED : 412,PAYLOAD_TOO_LARGE : 413,UNSUPPORTED_MEDIA_TYPE : 415,UNPROCESSABLE_CONTENT : 422,PRECONDITION_REQUIRED : 428,TOO_MANY_REQUESTS : 429,CLIENT_CLOSED_REQUEST : 499,INTERNAL_SERVER_ERROR : 500,NOT_IMPLEMENTED : 501,BAD_GATEWAY : 502,SERVICE_UNAVAILABLE : 503,GATEWAY_TIMEOUT : 504,} asconst ;
오류 코드 <-> JSON-RPC 2.0 오류 코드
사용 가능한 코드 & JSON-RPC 코드
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 constTRPC_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 errorINTERNAL_SERVER_ERROR : -32603, // 500NOT_IMPLEMENTED : -32603, // 501BAD_GATEWAY : -32603, // 502SERVICE_UNAVAILABLE : -32603, // 503GATEWAY_TIMEOUT : -32603, // 504// Implementation specific errorsUNAUTHORIZED : -32001, // 401PAYMENT_REQUIRED : -32002, // 402FORBIDDEN : -32003, // 403NOT_FOUND : -32004, // 404METHOD_NOT_SUPPORTED : -32005, // 405TIMEOUT : -32008, // 408CONFLICT : -32009, // 409PRECONDITION_FAILED : -32012, // 412PAYLOAD_TOO_LARGE : -32013, // 413UNSUPPORTED_MEDIA_TYPE : -32015, // 415UNPROCESSABLE_CONTENT : -32022, // 422PRECONDITION_REQUIRED : -32028, // 428TOO_MANY_REQUESTS : -32029, // 429CLIENT_CLOSED_REQUEST : -32099, // 499} asconst ;
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 constTRPC_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 errorINTERNAL_SERVER_ERROR : -32603, // 500NOT_IMPLEMENTED : -32603, // 501BAD_GATEWAY : -32603, // 502SERVICE_UNAVAILABLE : -32603, // 503GATEWAY_TIMEOUT : -32603, // 504// Implementation specific errorsUNAUTHORIZED : -32001, // 401PAYMENT_REQUIRED : -32002, // 402FORBIDDEN : -32003, // 403NOT_FOUND : -32004, // 404METHOD_NOT_SUPPORTED : -32005, // 405TIMEOUT : -32008, // 408CONFLICT : -32009, // 409PRECONDITION_FAILED : -32012, // 412PAYLOAD_TOO_LARGE : -32013, // 413UNSUPPORTED_MEDIA_TYPE : -32015, // 415UNPROCESSABLE_CONTENT : -32022, // 422PRECONDITION_REQUIRED : -32028, // 428TOO_MANY_REQUESTS : -32029, // 429CLIENT_CLOSED_REQUEST : -32099, // 499} asconst ;
기본 HTTP 메서드 오버라이드
쿼리/뮤테이션에 사용되는 HTTP 메서드를 오버라이드하려면 methodOverride 옵션을 사용할 수 있습니다:
server/httpHandler.tstsx// Your server must separately allow the client to override the HTTP methodconsthandler =createHTTPHandler ({router :router ,allowMethodOverride : true,});
server/httpHandler.tstsx// Your server must separately allow the client to override the HTTP methodconsthandler =createHTTPHandler ({router :router ,allowMethodOverride : true,});
client/trpc.tstsximport {createTRPCClient ,httpLink } from '@trpc/client';import type {AppRouter } from './server';// The client can then specify which HTTP method to use for all queries/mutationsconstclient =createTRPCClient <AppRouter >({links : [httpLink ({url : `http://localhost:3000`,methodOverride : 'POST', // all queries and mutations will be sent to the tRPC Server as POST requests.}),],});
client/trpc.tstsximport {createTRPCClient ,httpLink } from '@trpc/client';import type {AppRouter } from './server';// The client can then specify which HTTP method to use for all queries/mutationsconstclient =createTRPCClient <AppRouter >({links : [httpLink ({url : `http://localhost:3000`,methodOverride : 'POST', // all queries and mutations will be sent to the tRPC Server as POST requests.}),],});
심층 분석
다음의 TypeScript 정의에서 더 자세한 내용을 확인할 수 있습니다.