Elysia - Bun向け最速Webフレームワーク

2024.12.29

Elysiaとは

Elysiaは、Bunランタイム向けに最適化された高速なWebフレームワークです。End-to-End型安全性、エルゴノミックなAPI、驚異的なパフォーマンスが特徴です。

パフォーマンス

ベンチマーク(リクエスト/秒):
- Express (Node.js): 15,000
- Fastify (Node.js): 45,000
- Hono (Bun): 120,000
- Elysia (Bun): 150,000+

基本的な使い方

import { Elysia } from 'elysia';

const app = new Elysia()
  .get('/', () => 'Hello, Elysia!')
  .get('/user/:id', ({ params: { id } }) => `User ${id}`)
  .post('/users', ({ body }) => body)
  .listen(3000);

console.log(`🦊 Server running at ${app.server?.url}`);

型安全性

自動型推論

import { Elysia, t } from 'elysia';

const app = new Elysia()
  .post('/users', ({ body }) => {
    // bodyは自動的に型付け
    return { id: 1, ...body };
  }, {
    body: t.Object({
      name: t.String(),
      email: t.String({ format: 'email' }),
      age: t.Optional(t.Number())
    }),
    response: t.Object({
      id: t.Number(),
      name: t.String(),
      email: t.String(),
      age: t.Optional(t.Number())
    })
  });

End-to-End型安全クライアント

// server.ts
import { Elysia, t } from 'elysia';

export const app = new Elysia()
  .get('/users', () => [{ id: 1, name: 'Alice' }])
  .get('/users/:id', ({ params }) => ({ id: params.id, name: 'Alice' }))
  .post('/users', ({ body }) => ({ id: 1, ...body }), {
    body: t.Object({ name: t.String() })
  });

export type App = typeof app;

// client.ts
import { treaty } from '@elysiajs/eden';
import type { App } from './server';

const client = treaty<App>('http://localhost:3000');

// 完全な型推論
const users = await client.users.get();
const user = await client.users({ id: '1' }).get();
const newUser = await client.users.post({ name: 'Bob' });

プラグインシステム

組み込みプラグイン

import { Elysia } from 'elysia';
import { swagger } from '@elysiajs/swagger';
import { cors } from '@elysiajs/cors';
import { jwt } from '@elysiajs/jwt';

const app = new Elysia()
  .use(swagger())
  .use(cors())
  .use(jwt({
    name: 'jwt',
    secret: process.env.JWT_SECRET!
  }))
  .get('/protected', async ({ jwt, cookie: { auth } }) => {
    const profile = await jwt.verify(auth.value);
    if (!profile) throw new Error('Unauthorized');
    return profile;
  });

カスタムプラグイン

import { Elysia } from 'elysia';

const myPlugin = new Elysia({ name: 'my-plugin' })
  .decorate('myService', {
    greet: (name: string) => `Hello, ${name}!`
  })
  .derive(({ headers }) => ({
    userId: headers['x-user-id']
  }));

const app = new Elysia()
  .use(myPlugin)
  .get('/', ({ myService, userId }) => {
    return myService.greet(userId ?? 'Guest');
  });

ライフサイクル

const app = new Elysia()
  // リクエスト前
  .onBeforeHandle(({ request }) => {
    console.log(`${request.method} ${request.url}`);
  })
  // レスポンス後
  .onAfterHandle(({ response }) => {
    console.log('Response sent');
  })
  // エラーハンドリング
  .onError(({ error, code }) => {
    console.error(`Error: ${code}`, error);
    return { error: error.message };
  })
  .get('/', () => 'Hello');

グループとガード

const app = new Elysia()
  .group('/api', (app) =>
    app
      .guard({
        beforeHandle: ({ headers }) => {
          if (!headers['authorization']) {
            throw new Error('Unauthorized');
          }
        }
      })
      .get('/users', () => [])
      .get('/posts', () => [])
  )
  .listen(3000);

ストリーミング

import { Elysia } from 'elysia';

const app = new Elysia()
  .get('/stream', function* () {
    yield 'Hello ';
    yield 'World ';
    yield '!';
  })
  .get('/sse', ({ set }) => {
    set.headers['content-type'] = 'text/event-stream';
    return new ReadableStream({
      start(controller) {
        let count = 0;
        const interval = setInterval(() => {
          controller.enqueue(`data: ${count++}\n\n`);
          if (count >= 10) {
            clearInterval(interval);
            controller.close();
          }
        }, 1000);
      }
    });
  });

WebSocket

import { Elysia } from 'elysia';

const app = new Elysia()
  .ws('/ws', {
    message(ws, message) {
      ws.send(`Echo: ${message}`);
    },
    open(ws) {
      console.log('Connection opened');
    },
    close(ws) {
      console.log('Connection closed');
    }
  });

Swagger自動生成

import { Elysia, t } from 'elysia';
import { swagger } from '@elysiajs/swagger';

const app = new Elysia()
  .use(swagger({
    documentation: {
      info: { title: 'My API', version: '1.0.0' }
    }
  }))
  .get('/users', () => [], {
    response: t.Array(t.Object({
      id: t.Number(),
      name: t.String()
    })),
    detail: {
      summary: 'Get all users',
      tags: ['users']
    }
  });

// http://localhost:3000/swagger でドキュメント表示

まとめ

Elysiaは、Bunの性能を最大限に活かした高速なWebフレームワークです。End-to-End型安全性とエルゴノミックなAPIにより、型安全なフルスタックアプリケーションを効率的に構築できます。

← 一覧に戻る