🫥
oRPC + Better AuthをBunの組み込みサーバーで動かす
結論
index.ts
import { RPCHandler } from "@orpc/server/fetch";
import { CORSPlugin } from "@orpc/server/plugins";
import { router } from "./routes";
import { auth } from "./libs/auth";
const handler = new RPCHandler(router, {
plugins: [
new CORSPlugin({
origin: "http://localhost:3000",
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allowHeaders: ["Content-Type", "Authorization"],
credentials: true,
}),
],
});
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "http://localhost:3000",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true",
}
Bun.serve({
port: 8000,
async fetch(request: Request) {
const { matched, response } = await handler.handle(request, {
prefix: "/rpc",
context: {
headers: request.headers,
},
});
if (matched) {
return response;
}
if (request.method === "OPTIONS") {
return new Response("OK", { headers: CORS_HEADERS });
}
const url = new URL(request.url);
if (url.pathname.startsWith("/api/auth")) {
const response = await auth.handler(request);
Object.entries(CORS_HEADERS).forEach(([key, value]) => {
response.headers.set(key, value);
});
return response;
}
return new Response("Not found", { status: 404 });
},
});
このようにしてあげる。
解説
サーバーの起動・リッスン
他のフレームワーク(HonoやElysiaなど)と一緒にoRPCやBetter Authを使わない場合、Bunでは Bun.serve
で組み込みサーバーを使って動かすのがセオリー。
oRPCのGetting StartedにはNodeサーバーアダプタを使った方法しか乗ってないが、以下のドキュメントには Bun.serve
を使った方法が載っている
CORS
単にoRPCを使うだけなら、oRPCのCORSPluginを使えば、CORS関係のヘッダーが設定できるが、Better Authを使用する場合はBetter Authのルート用に個別にPreflight Requestをハンドリングしてあげるのと、Better AuthのハンドラからのレスポンスにCORSヘッダーを設定してあげる必要がある。
余談
今回のプロジェクトでは、ここからWebhookや外部連携用のAPIなども足していくことになったので、重厚になっちゃったとしても元からElysiaやHonoを使っておけばよかったなと思った。
(まぁでも今ならAIに任せればちゃちゃっとフレームワーク配下に置いてくれるけど)
以上
Discussion