はじめに
Hono は、Web 標準 API 上で動作する軽量の HTTP フレームワークで、高速、軽量、タイプセーフです。 xClaw は、すべての HTTP リクエストのエントリ ポイントである API ゲートウェイとして Hono を使用します。
1. Honoサーバーのセットアップ
// packages/gateway/src/gateway.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
export function createGateway() {
const app = new Hono();
// Global middleware
app.use('*', logger());
app.use('*', cors({
origin: process.env.CORS_ORIGINS?.split(',') ?? ['http://localhost:3001'],
credentials: true,
}));
// Health check
app.get('/health', (c) => {
return c.json({
status: 'ok',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
});
// Auth routes (public)
app.post('/auth/login', loginHandler);
app.post('/auth/register', registerHandler);
// Protected API routes
const api = new Hono();
api.use('*', authMiddleware); // JWT verification
api.use('*', rbacMiddleware); // Permission checking
api.post('/chat', chatHandler);
api.get('/models', modelsHandler);
api.route('/workflows', workflowRoutes);
api.route('/knowledge', knowledgeRoutes);
api.route('/monitoring', monitoringRoutes);
app.route('/api', api);
return app;
}
2. JWT 認証
// packages/gateway/src/auth.ts
import { sign, verify } from 'hono/jwt';
import { compare, hash } from 'bcrypt';
async function loginHandler(c: Context) {
const { email, password } = await c.req.json();
const user = await findUserByEmail(email);
if (!user) return c.json({ error: 'Invalid credentials' }, 401);
const valid = await compare(password, user.passwordHash);
if (!valid) return c.json({ error: 'Invalid credentials' }, 401);
const token = await sign(
{ sub: user.id, tenantId: user.tenantId, email: user.email },
process.env.JWT_SECRET!,
);
return c.json({ token, user: { id: user.id, name: user.name, email: user.email } });
}
// Auth middleware
async function authMiddleware(c: Context, next: Next) {
const header = c.req.header('Authorization');
if (!header?.startsWith('Bearer ')) {
return c.json({ error: 'Unauthorized' }, 401);
}
const token = header.slice(7);
const payload = await verify(token, process.env.JWT_SECRET!);
c.set('user', payload);
await next();
}
3. RBAC ミドルウェア
function requirePermission(...permissions: string[]) {
return async (c: Context, next: Next) => {
const user = c.get('user');
const userPerms = await getUserPermissions(user.sub, user.tenantId);
for (const perm of permissions) {
if (!userPerms.includes(perm)) {
return c.json({ error: 'Forbidden', required: perm }, 403);
}
}
await next();
};
}
// Usage
api.post('/workflows', requirePermission('workflows:create'), createWorkflowHandler);
api.delete('/workflows/:id', requirePermission('workflows:delete'), deleteWorkflowHandler);
4. まとめ
- Hono — 軽量、Web 標準、ミドルウェア チェーン
- JWT 認証 — ステートレス認証
- RBAC ミドルウェア — ルートごとの許可ベースのアクセス制御
- エラー処理 — 一貫した JSON エラー応答
次の記事: LLM ルーター — マルチプロバイダー LLM のアダプター パターン。