HonoでAPI構築 Durable Objectsも使っちゃうよ
Hono - Web framework built on Web Standards # Quick Start
を見てinstallする。そして
pnpm run deployで表示される***.workers.devにアクセス
Hello Hono!を確認。非常にspeedy。
OpenAPI doc & swagger UIを導入する
https://hono.dev/examples/swagger-ui?utm_source=chatgpt.com
を見ながら、swaggerのmiddlewareを入れる。こういうのが簡単に入れられるのもありがたい。client側もopenapiで合わせて生成したいので...
import { swaggerUI } from '@hono/swagger-ui'
import { Hono } from 'hono'
const openApiDoc = {
openapi: '3.0.0', // This is the required version field
info: {
title: 'API Documentation',
version: '1.0.0',
description: 'API documentation for your service',
},
paths: {
// Add your API paths here
'/health': {
get: {
summary: 'Health check',
responses: {
'200': {
description: 'OK',
},
},
},
},
// Add more endpoints as needed
},
}
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono!')
})
// Serve the OpenAPI document
app.get('/doc', (c) => c.json(openApiDoc))
// Use the middleware to serve Swagger UI at /ui
app.get('/ui', swaggerUI({ url: '/doc' }))
app.get('/health', (c) => c.text('OK'))
export default appCloudflare Durable Objectsを使用する
https://developers.cloudflare.com/durable-objects/get-started/#1-create-a-worker-project
に倣って、別projectとして一旦durable objectを使用したprojectをデプロイする。
先程honoで作成したprojectのほうにもDurable Objectsを適用するためには、wrangler.jsonc (またはwrangler.toml)及びDurableObjects用のクラスを作成する必要があることがわかる。
以下をwrangler.jsoncに追加する。
"durable_objects": {
"bindings": [
{
"name": "DO_NAME",
"class_name": "TypeScriptClassName"
}
]
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["TypeScriptClassName"]
}
]DO_NAMEとなっている箇所にはDurable Objectsの名前を、TypeScriptClassNameとなっている箇所には後ほど定義するTypeScriptのクラス名を記載する。
TypeScriptClassName.tsで以下のようにクラスを定義する。
export class TypeScriptClassName extends DurableObject<Env> {
private sql: SqlStorage;
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.sql = ctx.storage.sql;
this.sql.exec(`
CREATE TABLE IF NOT EXISTS sample_table (
id INTEGER PRIMARY KEY
, uuid BLOG(16) UNIQUE NOT NULL
);
`);
}
async insert(): Promise<void> {
this.sql.exec(`INSERT INTO dive_queue (uuid) VALUES (?)`, [
crypto.randomUUID()
]);
}
}honoのindex.tsで以下のようにgetStub utilityメソッドを用意する。
このときEnvはworker-configuration.d.tsで定義されたものを使用する。
worker-configuration.d.tsはpnpm wrangler typesコマンドに寄ってwrangler.jsonc(またはtoml)を見て生成される。
Durable Objectsの内容に更新がある場合は都度コマンドの実行が必要。
ref. https://developers.cloudflare.com/workers/languages/typescript/
function getStub(env: Env): DurableObjectStub<DiveQueue> {
const id = env.DO_NAME.idFromName('global');
return env.DO_NAME.get(id) as DurableObjectStub<DiveQueue>;
}このとき、idFromNameを一定のglobalなどにすると全リクエストで同一のDurable Objectsインスタンスを参照 / 更新することになり簡易的な単一ストレージのように使用することができる。
ref. https://developers.cloudflare.com/durable-objects/api/namespace/#methods
https://developers.cloudflare.com/durable-objects/api/sqlite-storage-api/
使用することができるSQL APIはここを見ると良い。
localで開発する際に、wranglerがモックしているDurable Objectsをリセットしたい場合は.wranglerディレクトリを削除すると良い。
Durable Objects - alarmを使用する
https://developers.cloudflare.com/durable-objects/api/alarms/
ゴミデータをあとから削除するなど、遅延実行や定期実行をしたい場合にDurable Objectsのアラーム機能を使用することができる。