はじめに
前から思ってたんだけど、タイプセーフな言語で開発できて、ドキュメントの手動更新もいらなくて、しかもきれいに可視化できたらいいよなーって。
そしたら、どうやらBun
とHono
とReDoc
を使えばそれができちゃうらしいです。
そもそもこいつらって何?
Bun
Bunは、最新のJavaScriptエコシステムに対応するため、ゼロから構築された新しいJavaScriptランタイムです、しかも非常に早くて、NodeJsより3倍近く速いらしいです。公式ドキュメント
この記事でBunを使うメリットは特にないんだけど、最近の流行りに乗っかりたいだけです。
Hono
高速で軽量、しかもWeb標準に基づいて作られてて、あらゆるJavaScriptランタイムをサポートしてるらしいです。
使ってみた感想としては、TypeScriptで書かれた現代のExpressって感じ。リリースされてから、NestJSを超える人気が出てるし、しかも作者は日本人。第2のRuby on Railsになることを期待してます。 公式ドキュメント
ReDoc
ReDocはOpenAPI(Swagger)仕様を基にしてAPIのドキュメントを生成するツールです。HonoでSwaggerUIを使うのも簡単なんだけど、個人的にはReDocのUIの方がきれいなので、ReDocを使います。リポジトリ
事前準備
Bunをインストールします。
- Homebrew
% brew install oven-sh/bun/bun
- npm
% npm install -g bun
インストール完了後、バージョン確認できます。
% bun -v
> 1.1.33
Honoのプロジェクト作成
bunx
コマンド使って初期化します。
% bunx create-hono
create-hono version 0.14.2
? Target directory bun-hono-api
? Which template do you want to use? cloudflare-workers
? Do you want to install project dependencies? yes
? Which package manager do you want to use? bun
✔ Cloning the template
✔ Installing project dependencies
🎉 Copied project files
Get started with: cd bun-hono-api
初期化されたプロジェクトには、以下のようなエントリーファイルがあります。
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono!')
})
export default app
このコードは、ルート /
にアクセスしたときに Hello Hono!
を返すシンプルなAPIを定義しています。
次に、以下のコマンドを実行し、ブラウザで http://localhost:8787 にアクセスすると、Hello Hono! というメッセージが表示されます。
% bun run dev
wrangler dev
⛅️ wrangler 3.83.0
-------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
@hono/zod-openapiインストール
% bun add @hono/zod-openapi
@hono/zod-openapi
は、HonoとZodライブラリを統合し、OpenAPIに準拠したスキーマを定義・管理するためのツールです。
これを使うと、スキーマからAPIルートやバリデーションロジックを自動生成できます
しかも、作者のお墨付きももらってます。
実際@hono/zod-openapi使ってルート /
を改造しましょう。
import { OpenAPIHono as Hono, z, createRoute } from '@hono/zod-openapi';
const app = new Hono()
export const rootSchema = z.object({
code: z.number().openapi({
example: 200,
}),
message: z.string().openapi({
example: 'Hello Hono!',
}),
});
const rootRoute = createRoute({
method: 'get',
summary: 'root route',
description: 'use health check',
path: '/',
request: {},
responses: {
200: {
content: {
'application/json': {
schema: rootSchema,
},
},
description: 'root router return Hello Hono',
},
},
tags: ['Root'],
});
app.openapi(rootRoute, (c) => {
return c.json({ code: 200, message: 'Hello Hono!' });
});
export default app
スキーマを追加することで、レスポンスの形式が厳密に定義されました。
再度以下のコマンドを実行し、ブラウザで http://localhost:8787 にアクセスすると、{"code":200,"message":"Hello Hono!"}
というメッセージが表示されます。
% bun run dev
wrangler dev
⛅️ wrangler 3.83.0
-------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
レスポンスからcode
を削除してみます。
app.openapi(rootRoute, (c) => {
- return c.json({ message: 'Hello Hono!' });
});
ReDoc追加
まず、src/index.ts
をsrc/index.tsx
に変更します。
wrangler.toml
のmainを下記のように修正。
name = "bun-hono-api"
+ main = "src/index.tsx"
compatibility_date = "2024-10-30"
...略
... 略
app.openapi(rootRoute, (c) => {
return c.json({ code: 200, message: 'Hello Hono!' });
});
+ app.doc('/openapi-spec.json', {
+ openapi: '3.0.0',
+ info: {
+ version: 'v1',
+ title: 'Sample ToDo list API',
+ description:
+ 'This API exhibits how you can provide a comprehensible API documentation using [Hono](https://hono.dev), [Redoc](https://redocly.com/docs/redoc/).',
+ 'x-logo': {
+ url: 'https://raw.githubusercontent.com/honojs/hono/main/docs/images/hono-title.png',
+ altText: 'Sample ToDo API logo',
+ },
+ },
+ tags: [
+ { name: 'Root', description: 'Root route' },
+ ],
+ });
+ app.get('/docs/redoc', (c) =>
+ c.html(
+ <html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <meta name="description" content="SwaggerUI" />
+ <title>Sample API | Redoc</title>
+ </head>
+ <body>
+ <redoc spec-url="/openapi-spec.json"></redoc>
+ <script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js">+ </script>
+ </body>
+ </html>,
+ ),
+ );
export default app
サーバー立ち上げて、http://localhost:8787/docs/redoc にアクセスすれば、ReDoc確認できると思います。
UIのカスタマイズする際には公式ドキュメントを参考してください。
また、swagger-ui使用したい場合はこちらのドキュメントを参考にしてください。
補足
本記事では、Cloudflare Workersに対応したHonoプロジェクトを初期化しました。
以下のコマンドを実行すれば、Cloudflare Workersにデプロイできます。
bun run deploy
動作検証も済みです。
AWS ECS
にデプロイしたい場合、下記の修正を加えれば、対応できます。
..略
- export default app;
+ export default {
+ port: 3000,
+ fetch: app.fetch,
+ };
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy --minify",
+ "start": "bun run src/index.tsx"
}
# build
FROM oven/bun:latest
WORKDIR /app
COPY package.json ./
RUN bun install --production
COPY . .
EXPOSE 3000
CMD ["bun", "run", "start"]
最後に
ReDocの便利なカスタマイズ方法があれば、ぜひ教えてください。