Open9

tRPCはどんな通信をしているのか

GenGen

git cloneすると結構deprecatedになっている箇所がある。yarnしてyarn startで動くのでdeprecatedは気にしないことにした。

GenGen

router抜粋

const helloRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }).nullish())
    .query((arg) => {
      console.log(arg);

      return `Hello ${arg.input?.name ?? 'World'}`;
    }),
});

export const appRouter = t.router({
  hello: helloRouter,
});

server

async function main() {
  // express implementation
  const app = express();

  // For testing purposes, wait-on requests '/'
  app.get('/', (_req, res) => res.send('Server is running!'));

  app.use(
    '/trpc',
    createExpressMiddleware({
      router: appRouter,
      createContext: () => ({}),
    }),
  );
  app.listen(3000);
}

localhost:3000/trpc配下にアクセスするとtrpc routerが動く。
queryとかがどういうパス、リクエストbodyに対応するのか見てみる。

GenGen

とりあえずyarn startしてサーバが動いている状態にしてからPostmanで雑にlocalhost:3000/trpcにGETを投げてみた。
以下、レスポンス。

{
    "error": {
        "message": "No \"query\"-procedure on path \"\"",
        "code": -32004,
        "data": {
            "code": "NOT_FOUND",
            "httpStatus": 404,
            "stack": "TRPCError: No \"query\"-procedure on path \"\"\n    at callProcedure (/Users/xxxx/xxxx/trpc/packages/server/dist/router-da6086c3.js:636:15)\n    at (略),
            "path": ""
        }
    }
}

「/というpathにはqueryプロシージャが無い」とのこと。

GenGen

色々見た結果routerの設定からpathが決まるらしい。

router抜粋

const helloRouter = t.router({
  greeting: t.procedure
// ^^^^^^ ここと
    .input(z.object({ name: z.string() }).nullish())
    .query((arg) => {
      console.log(arg);

      return `Hello ${arg.input?.name ?? 'World'}`;
    }),
});

export const appRouter = t.router({
  hello: helloRouter,
// ^^^^^ ここ
});

routerが入れ子になっているかしょは.で接続される。

GenGen

従ってlocalhost:3000/trpc/hello.greetingにアクセスすると以下のレスポンスを得ることができた。

{
    "result": {
        "data": "Hello World"
    }
}
GenGen

queryのargに値を渡すためにはquery文字列に

input={"key":"value"}

の形でJSONを渡すと認識してくれる。

例えばlocalhost:3000/trpc/hello.greeting?input={"name":"taro"}でGETリクエストすると

{
    "result": {
        "data": "Hello taro"
    }
}

となる。

GenGen

ちなみに同じURLにPOSTで投げると

{
    "error": {
        "message": "No \"mutation\"-procedure on path \"hello.greeting\"",
        "code": -32004,
        "data": {
            "code": "NOT_FOUND",
            "httpStatus": 404,
            "stack": "TRPCError: No \"mutation\"-procedure on path \"hello.greeting\"\n    at (略),
            "path": "hello.greeting"
        }
    }
}

となり、hello.greetingパスにmutationプロシージャが無いよ、というエラーになる。

HTTPメソッドによってrouter内で解決されるhandlerを切り分けているんですね。