🧊

`Bun.serve()`だけでルーターが書けるようになってた

以前にも、手元で動かすProxyサーバーを書くのにBunが便利だという記事を書いてた。

ローカルProxyサーバーをBunで書く | Memory ice cubes https://leaysgur.github.io/posts/2023/06/21/094744/

けど、この度また使ってみたら、さらに便利になっていた・・・!

ルーターが同梱された

つまり、このコードがBunだけで動く。

import { Database } from "bun:sqlite";

interface Post {
  id: string;
  title: string;
  content: string;
  created_at: string;
}

const db = new Database("posts.db");
db.exec(`
  CREATE TABLE IF NOT EXISTS posts (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT NOT NULL,
    created_at TEXT NOT NULL
  )
`);

Bun.serve({
  routes: {
    "/api/posts": {
      GET: () => {
        const posts = db.query("SELECT * FROM posts").all();
        return Response.json(posts);
      },

      POST: async (req) => {
        const post: Omit<Post, "id" | "created_at"> = await req.json();
        const id = crypto.randomUUID();

        db.query(
          `INSERT INTO posts (id, title, content, created_at)
           VALUES (?, ?, ?, ?)`,
        ).run(id, post.title, post.content, new Date().toISOString());

        return Response.json({ id, ...post }, { status: 201 });
      },
    },

    "/api/posts/:id": (req) => {
      const post = db
        .query("SELECT * FROM posts WHERE id = ?")
        .get(req.params.id);

      if (!post) return new Response("Not Found", { status: 404 });
      return Response.json(post);
    },
  },

  error(error) {
    console.error(error);
    return new Response("Internal Server Error", { status: 500 });
  },
});

DBのところはさておき、

  • routes配下に直接ルートを定義できる
  • GETPOSTのようにメソッドごとにも定義できる
  • error()でルートのエラーハンドラにできる

もちろん一般的なルーター実装と比べると、まだ機能不足やとは思うし、パフォーマンスも比較したわけではないけど、ちょっとしたローカルサーバーを書くだけなら必要十分だなと。

HTTP server – API | Bun Docs https://bun.sh/docs/api/http

2月末にリリースされてたのか〜。

Bun v1.2.3 | Bun Blog https://bun.sh/blog/bun-v1.2.3#built-in-routing-for-bun-serve