mcpField
F
fastify-typescript

fastify-typescript

github.com/mindrally開発287861 回インストール3 週間前に更新
リポジトリ

fastify-typescript について

Fastify と TypeScript で型安全な API を構築するためのスキルです。ルート設計、検証、プラグイン、データアクセス、テスト、セキュリティの指針を扱います。

主な機能

  1. 01TypeScript の型付けと命名規則
  2. 02Fastify ルートのモジュール化
  3. 03TypeBox による JSON Schema 検証
  4. 04プラグインとデコレーターのパターン
  5. 05Prisma のデータアクセス指針
  6. 06テストとセキュリティの実践

活用シーン

  1. 01リソース別の Fastify API 構成
  2. 02型安全なリクエスト・レスポンス検証の追加
  3. 03プラグインを介した Prisma の統合
  4. 04ルートテストと API セキュリティの計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mindrally/skills --skill fastify-typescript

インストール後、Claude Code で/fastify-typescriptを入力して読み込まれたか確認します。

詳細

Fastify と TypeScript の開発

高いパフォーマンスと型安全性を備えた API の構築に関する深い知識を持つ、Fastify と TypeScript 開発のエキスパートです。

TypeScript の一般的なガイドライン

基本原則
  • すべてのコードとドキュメントには英語を使用します
  • 変数と関数(引数と戻り値)には必ず型を宣言します
  • any 型の使用は避け、必要な型を作成します
  • 公開クラスとメソッドのドキュメントには JSDoc を使用します
  • 簡潔で保守しやすく、技術的に正確なコードを書きます
  • 関数型および宣言型のプログラミングパターンを使用し、クラスは避けます
  • DRY 原則に従い、反復とモジュール化を優先します
命名規則
  • 型とインターフェースには PascalCase を使用します
  • 変数、関数、メソッドには camelCase を使用します
  • ファイル名とディレクトリ名には kebab-case を使用します
  • 環境変数には UPPERCASE を使用します
  • isLoading、hasError、canDelete のように、助動詞を使った説明的な変数名を使用します
  • 各関数の名前は動詞で始めます
関数
  • 関数は単一の目的を持つ短いものにします
  • 単純な処理にはアロー関数を使用します
  • コードベース全体で一貫して async/await を使用します
  • 複数の引数には RO-RO パターン(オブジェクトを受け取り、オブジェクトを返す)を使用します
型とインターフェース
  • オブジェクトの形状には、型よりインターフェースを優先します
  • enum は避け、代わりにマップまたは const オブジェクトを使用します
  • 実行時の検証には Zod を使用し、型を推論します
  • 不変プロパティには readonly を使用します
  • 型のみをインポートする場合は import type を使用します

Fastify 固有のガイドライン

プロジェクト構成
src/
  routes/
    {resource}/
      index.ts
      handlers.ts
      schemas.ts
  plugins/
    auth.ts
    database.ts
    cors.ts
  services/
    {domain}Service.ts
  repositories/
    {entity}Repository.ts
  types/
    index.ts
  utils/
  config/
  app.ts
  server.ts
ルートの構成
  • リソースまたはドメインごとにルートを整理します
  • モジュール形式で登録するにはルートプラグインを使用します
  • ルートハンドラーと並べてスキーマを定義します
  • API のバージョン管理にはルートプレフィックスを使用します
import { FastifyPluginAsync } from 'fastify';

const usersRoutes: FastifyPluginAsync = async (fastify) => {
  fastify.get('/', { schema: listUsersSchema }, listUsersHandler);
  fastify.get('/:id', { schema: getUserSchema }, getUserHandler);
  fastify.post('/', { schema: createUserSchema }, createUserHandler);
  fastify.put('/:id', { schema: updateUserSchema }, updateUserHandler);
  fastify.delete('/:id', { schema: deleteUserSchema }, deleteUserHandler);
};

export default usersRoutes;
JSON Schema / Ajv によるスキーマ検証
  • すべてのリクエストとレスポンスの検証に JSON スキーマを定義します
  • 型安全なスキーマ定義には @sinclair/typebox を使用します
  • Fastify に組み込まれている Ajv 連携を活用します
import { Type, Static } from '@sinclair/typebox';

const UserSchema = Type.Object({
  id: Type.String({ format: 'uuid' }),
  name: Type.String({ minLength: 1 }),
  email: Type.String({ format: 'email' }),
  createdAt: Type.String({ format: 'date-time' }),
});

type User = Static<typeof UserSchema>;

const createUserSchema = {
  body: Type.Object({
    name: Type.String({ minLength: 1 }),
    email: Type.String({ format: 'email' }),
  }),
  response: {
    201: UserSchema,
    400: ErrorSchema,
  },
};
プラグインとデコレーター
  • 共通機能にはプラグインを使用します
  • Fastify インスタンスにサービスとユーティリティをデコレートします
  • 適切なカプセル化を行ってプラグインを登録します
import fp from 'fastify-plugin';

const databasePlugin = fp(async (fastify) => {
  const prisma = new PrismaClient();

  await prisma.$connect();

  fastify.decorate('prisma', prisma);

  fastify.addHook('onClose', async () => {
    await prisma.$disconnect();
  });
});

export default databasePlugin;
Prisma との連携
  • データベース操作には ORM として Prisma を使用します
  • データアクセス用のリポジトリークラスを作成します
  • 複雑な操作にはトランザクションを使用します
class UserRepository {
  constructor(private prisma: PrismaClient) {}

  async findById(id: string): Promise<User | null> {
    return this.prisma.user.findUnique({ where: { id } });
  }

  async create(data: CreateUserInput): Promise<User> {
    return this.prisma.user.create({ data });
  }
}
エラー処理
  • Fastify に組み込まれているエラー処理を使用します
  • ドメインエラー用のカスタムエラークラスを作成します
  • 一貫性のあるエラーレスポンスを返します
import { FastifyError } from 'fastify';

class NotFoundError extends Error implements FastifyError {
  code = 'NOT_FOUND';
  statusCode = 404;

  constructor(resource: string, id: string) {
    super(`${resource} with id ${id} not found`);
    this.name = 'NotFoundError';
  }
}

// Global error handler
fastify.setErrorHandler((error, request, reply) => {
  const statusCode = error.statusCode || 500;

  reply.status(statusCode).send({
    error: error.name,
    message: error.message,
    statusCode,
  });
});
Jest によるテスト
  • サービスとハンドラーのユニットテストを作成します
  • ルートには統合テストを使用します
  • 外部依存関係をモックします
import { build } from '../app';

describe('Users API', () => {
  let app: FastifyInstance;

  beforeAll(async () => {
    app = await build();
  });

  afterAll(async () => {
    await app.close();
  });

  it('should list users', async () => {
    const response = await app.inject({
      method: 'GET',
      url: '/api/users',
    });

    expect(response.statusCode).toBe(200);
    expect(JSON.parse(response.payload)).toBeInstanceOf(Array);
  });
});
パフォーマンス
  • Fastify は Node.js フレームワークの中でも特に高速です
  • スキーマ検証を使用して、シリアライズを自動的に最適化します
  • 本番環境では必要な場合にのみロギングを有効にします
  • データベース接続にはコネクションプーリングを使用します
セキュリティ
  • セキュリティヘッダーには @fastify/helmet を使用します
  • @fastify/rate-limit でレート制限を実装します
  • CORS の設定には @fastify/cors を使用します
  • JSON Schema ですべての入力を検証します
  • @fastify/jwt を使用して JWT 認証を実装します

コメント