Skip to content
cccskills
FreePublished on GitHub

api-design

RESTful API の設計を行います。エンドポイント定義、リクエスト/レスポンス仕様、エラーハンドリング、ScalarDBトランザクション例外のマッピングを含みます。

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md23.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

API Design Skill

目的

システムのRESTful APIを設計し、以下を定義します:

  1. エンドポイント設計: URL設計、HTTPメソッド、パス構造
  2. リクエスト/レスポンス仕様: DTO定義、バリデーション
  3. エラーハンドリング: エラーコード、エラーレスポンス形式、ScalarDBトランザクション例外のマッピング
  4. OpenAPI仕様書: Swagger/OpenAPI 3.0形式
  5. CDCメタデータのフィルタリング: tx_stateなどの内部カラムの除外
  6. サービス間通信設計: ScalarDB 2PCを利用したマイクロサービス間通信パターン

参照ドキュメント

ドキュメントパス説明
API設計手順workflow/06_api_interface_design.mdAPI設計の詳細ステップ
データアクセスパターンresearch/08_transparent_data_access.mdScalarDBの透過的データアクセス設計
マイクロサービスアーキテクチャresearch/01_microservice_architecture.mdMSAパターンとサービス分割

入力パラメータ

パラメータ必須説明デフォルト
projectNameYesプロジェクト名-
apiVersionNoAPIバージョンv1
baseUrlNoベースURL/api/v1
authTypeNo認証方式Bearer

API設計原則

RESTful設計原則

原則説明例
リソース指向名詞でリソースを表現/users, /audit-sets
HTTPメソッド操作をメソッドで表現GET=取得, POST=作成
ステートレスセッション状態を持たないトークン認証
統一インターフェース一貫したURL設計/resources/{id}

HTTPメソッドマッピング

メソッド操作成功コードべき等性
GET取得200Yes
POST作成201No
PUT全体更新200Yes
PATCH部分更新200No
DELETE削除204Yes

ScalarDB トランザクション例外のAPIマッピング

ScalarDBのトランザクション例外をHTTPステータスコードに適切にマッピングし、クライアントに対して適切なリトライ戦略を提供します。

リトライ可能な競合エラー (409 Conflict)

ScalarDB例外HTTPステータスエラーコードリトライ戦略
CrudConflictException409 ConflictSCALARDB_001Exponential backoff でリトライ推奨
CommitConflictException409 ConflictSCALARDB_002Exponential backoff でリトライ推奨

レスポンス例:

{
  "error": {
    "code": "SCALARDB_001",
    "message": "データ競合が発生しました。リトライしてください",
    "details": {
      "exception": "CrudConflictException",
      "retryable": true,
      "retryStrategy": "exponential_backoff",
      "recommendedWaitMs": 1000
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

不明なトランザクション状態 (500 + リトライガイダンス)

ScalarDB例外HTTPステータスエラーコードリトライ戦略
UnknownTransactionStatusException500 Internal Server ErrorSCALARDB_003べき等性を確認してからリトライ

レスポンス例:

{
  "error": {
    "code": "SCALARDB_003",
    "message": "トランザクションの状態が不明です",
    "details": {
      "exception": "UnknownTransactionStatusException",
      "retryable": true,
      "retryStrategy": "idempotent_retry",
      "guidance": "操作がべき等であることを確認してからリトライしてください",
      "checkEndpoint": "/api/v1/transactions/{transactionId}/status"
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

リトライ不可能なエラー

ScalarDB例外HTTPステータスエラーコード説明
CommitException500 Internal Server ErrorSCALARDB_004トランザクションのコミット失敗
UnsatisfiedConditionException422 Unprocessable EntitySCALARDB_005条件付き更新の条件不一致

UnsatisfiedConditionException のレスポンス例:

{
  "error": {
    "code": "SCALARDB_005",
    "message": "更新条件が満たされていません",
    "details": {
      "exception": "UnsatisfiedConditionException",
      "retryable": false,
      "reason": "Expected version does not match current version",
      "expectedCondition": {
        "field": "version",
        "expectedValue": 5,
        "actualValue": 6
      }
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

エラーハンドリングのベストプラクティス

  1. クライアント側のリトライ実装

    • 409 Conflictの場合: Exponential backoffでリトライ
    • 500 + UnknownTransactionStatus: べき等性確認後にリトライ
    • 422 UnsatisfiedCondition: リトライせずエラー処理
  2. サーバー側の実装

    • トランザクションIDをログに記録
    • 分散トレーシングでトランザクション追跡
    • メトリクスで競合率を監視
  3. モニタリング

    • 409エラーの頻度を監視し、ホットスポットを検出
    • 500エラー(UnknownTransactionStatus)の発生を監視

CDCメタデータのフィルタリング

ScalarDB のChange Data Capture (CDC)機能で使用される内部メタデータカラムをAPIレスポンスから除外します。

フィルタリング対象カラム

カラム名説明フィルタリング理由
tx_stateトランザクション状態内部管理用、クライアントに不要
tx_idトランザクションID内部管理用、クライアントに不要
tx_prepared_atトランザクション準備時刻内部管理用、クライアントに不要
tx_committed_atトランザクションコミット時刻内部管理用、クライアントに不要
tx_versionトランザクションバージョン内部管理用、クライアントに不要
before_tx_idCDC用の前トランザクションIDCDC内部用
before_stateCDC用の前状態CDC内部用
before_versionCDC用の前バージョンCDC内部用
before_prepared_atCDC用の前準備時刻CDC内部用
before_committed_atCDC用の前コミット時刻CDC内部用

フィルタリング実装パターン

1. DTOレイヤーでのフィルタリング

@JsonIgnoreProperties(value = {
    "tx_state", "tx_id", "tx_prepared_at", "tx_committed_at", "tx_version",
    "before_tx_id", "before_state", "before_version",
    "before_prepared_at", "before_committed_at"
})
public class UserResponse {
    private String id;
    private String email;
    private String name;
    // ビジネスフィールドのみ
}

2. マッパーでの明示的フィルタリング

public class UserMapper {
    public UserResponse toResponse(Result result) {
        return UserResponse.builder()
            .id(result.getValue("id").get().getAsString())
            .email(result.getValue("email").get().getAsString())
            .name(result.getValue("name").get().getAsString())
            // CDCメタデータは意図的に除外
            .build();
    }
}

3. 共通フィルタークラス

public class CdcMetadataFilter {
    private static final Set<String> CDC_METADATA_COLUMNS = Set.of(
        "tx_state", "tx_id", "tx_prepared_at", "tx_committed_at", "tx_version",
        "before_tx_id", "before_state", "before_version",
        "before_prepared_at", "before_committed_at"
    );

    public static Map<String, Object> filterCdcMetadata(Map<String, Object> data) {
        return data.entrySet().stream()
            .filter(entry -> !CDC_METADATA_COLUMNS.contains(entry.getKey()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }
}

APIレスポンス例

フィルタリング前(NG):

{
  "id": "user-001",
  "email": "user@example.com",
  "name": "山田太郎",
  "tx_state": "COMMITTED",
  "tx_id": "tx-12345",
  "tx_version": 3,
  "before_tx_id": "tx-12344"
}

フィルタリング後(OK):

{
  "id": "user-001",
  "email": "user@example.com",
  "name": "山田太郎",
  "createdAt": "2026-02-17T10:00:00Z",
  "updatedAt": "2026-02-17T12:00:00Z"
}

サービス間通信設計

ScalarDB 2PC(Two-Phase Commit)を利用したマイクロサービス間の分散トランザクション設計。

サービス間通信パターン

1. Orchestration パターン(推奨)

サービス間の分散トランザクションをオーケストレーターが調整。

[Order Service] (Orchestrator)
    |
    ├─> [Inventory Service] (Participant)
    ├─> [Payment Service] (Participant)
    └─> [Shipping Service] (Participant)

実装例:

// Order Service (Orchestrator)
public class OrderOrchestrator {
    @POST
    @Path("/orders")
    public Response createOrder(OrderRequest request) {
        TwoPhaseCommitTransaction tx = manager.start();
        try {
            // 1. 在庫予約(Participant 1)
            inventoryClient.reserve(tx.getId(), request.getItems());

            // 2. 支払い処理(Participant 2)
            paymentClient.process(tx.getId(), request.getPayment());

            // 3. 配送手配(Participant 3)
            shippingClient.arrange(tx.getId(), request.getAddress());

            // 4. 注文作成(Coordinator)
            Order order = createOrderRecord(tx, request);

            tx.prepare();
            tx.commit();

            return Response.status(201).entity(order).build();
        } catch (CrudConflictException | CommitConflictException e) {
            tx.rollback();
            return Response.status(409).entity(new ConflictError(e)).build();
        } catch (Exception e) {
            tx.rollback();
            return Response.status(500).entity(new ServerError(e)).build();
        }
    }
}

2. Saga パターン(代替案)

各サービスがローカルトランザクションを実行し、補償トランザクションで整合性を保つ。

Order Created → Reserve Inventory → Process Payment → Arrange Shipping
     ↓              ↓                    ↓                  ↓
  Rollback ← Cancel Reservation ← Refund ← Cancel Shipping

API設計ガイドライン

トランザクションIDの伝播

ヘッダーでの伝播:

POST /api/v1/inventory/reserve
Authorization: Bearer {token}
X-Transaction-Id: tx-12345-67890
X-Request-Id: req-abc-def
Content-Type: application/json

{
  "items": [
    {"productId": "prod-001", "quantity": 2}
  ]
}

べき等性の保証

分散トランザクションでのリトライに備えてべき等性を実装。

@POST
@Path("/inventory/reserve")
@Idempotent
public Response reserveInventory(
    @HeaderParam("X-Transaction-Id") String txId,
    ReservationRequest request) {

    // 既に処理済みかチェック
    if (reservationRepository.exists(txId, request.getProductId())) {
        return Response.status(200).build(); // べき等性
    }

    // 予約処理
    reservation = reservationService.reserve(txId, request);
    return Response.status(201).entity(reservation).build();
}

タイムアウト設計

操作タイプタイムアウト理由
Prepare30秒各サービスの準備完了待ち
Commit60秒全サービスのコミット完了待ち
Rollback30秒ロールバックは速やかに完了すべき
サービス間HTTP10秒ネットワーク遅延を考慮

エラーハンドリング

Participant側のエラーレスポンス:

{
  "error": {
    "code": "INVENTORY_INSUFFICIENT",
    "message": "在庫が不足しています",
    "details": {
      "productId": "prod-001",
      "requested": 10,
      "available": 5,
      "transactionId": "tx-12345"
    },
    "retryable": false
  }
}

Orchestrator側のエラーハンドリング:

try {
    inventoryClient.reserve(txId, items);
} catch (InsufficientInventoryException e) {
    // ビジネスエラー: リトライせずロールバック
    tx.rollback();
    return Response.status(422).entity(toErrorResponse(e)).build();
} catch (ServiceUnavailableException e) {
    // 一時的エラー: リトライ可能
    tx.rollback();
    return Response.status(503).entity(toRetryableError(e)).build();
}

サービス間通信のベストプラクティス

  1. Circuit Breaker の実装

    • サービス障害時の連鎖防止
    • タイムアウトとリトライの制御
  2. 分散トレーシング

    • トランザクションIDとリクエストIDの伝播
    • OpenTelemetry/Zipkinでの追跡
  3. 非同期処理の活用

    • 長時間処理はイベント駆動で分離
    • ScalarDB 2PCは同期的な短時間処理に限定
  4. 部分的な失敗への対処

    • 適切なロールバック処理
    • 補償トランザクションの実装

実行フロー

Stage 1: 既存API分析

1.1 コントローラーの調査
    - エンドポイント一覧
    - リクエスト/レスポンス型
    - 認証・認可設定

1.2 問題点の特定
    - REST原則違反
    - 命名規則の不一致
    - バージョニングの欠如
    - ScalarDB例外の不適切なマッピング
    - CDCメタデータの漏洩

Stage 2: リソース設計

2.1 リソースの特定
    - ドメインモデルからの抽出
    - 集約ルートの特定
    - サブリソースの定義

2.2 URL設計
    - 階層構造の設計
    - クエリパラメータの設計
    - フィルタリング・ソート

Stage 3: エンドポイント設計

3.1 CRUD操作
    - 一覧取得 (GET /resources)
    - 詳細取得 (GET /resources/{id})
    - 作成 (POST /resources)
    - 更新 (PUT/PATCH /resources/{id})
    - 削除 (DELETE /resources/{id})

3.2 カスタムアクション
    - アクション系 (POST /resources/{id}/actions)
    - バッチ操作 (POST /resources/batch)

3.3 サービス間通信エンドポイント
    - 2PC参加エンドポイント
    - トランザクション状態確認

Stage 4: リクエスト/レスポンス設計

4.1 リクエスト設計
    - パスパラメータ
    - クエリパラメータ
    - リクエストボディ
    - ヘッダー(X-Transaction-Id等)

4.2 レスポンス設計
    - 成功レスポンス
    - エラーレスポンス(ScalarDB例外含む)
    - ページネーション
    - CDCメタデータのフィルタリング

Stage 5: エラーハンドリング設計

5.1 HTTPステータスコード
    - 2xx: 成功
    - 4xx: クライアントエラー
    - 5xx: サーバーエラー

5.2 ScalarDB例外のマッピング
    - CrudConflictException → 409
    - CommitConflictException → 409
    - UnknownTransactionStatusException → 500
    - CommitException → 500
    - UnsatisfiedConditionException → 422

5.3 エラーレスポンス形式
    - エラーコード体系
    - リトライ戦略の提示
    - 詳細情報

Stage 6: OpenAPI仕様書生成

出力

output/phase2/06_api_interface_design.md

出力フォーマット

# API設計書

## 概要

| 項目 | 値 |
|------|-----|
| APIバージョン | v1 |
| ベースURL | /api/v1 |
| 認証方式 | Bearer Token (JWT) |
| コンテンツタイプ | application/json |

## 設計原則

### URL設計規則

- リソース名は複数形(kebab-case)
- IDはUUID形式
- ネストは2階層まで
- クエリパラメータはcamelCase

### 認証・認可

- すべてのエンドポイントで認証必須(一部除く)
- JWT Bearer Token をAuthorizationヘッダーで送信
- ロールベースアクセス制御(RBAC)

### ScalarDB固有の設計

- トランザクション例外の適切なHTTPマッピング
- CDCメタデータのフィルタリング
- 分散トランザクションのためのトランザクションID伝播

## リソース一覧

| # | リソース | ベースパス | 説明 |
|---|---------|-----------|------|
| 1 | Users | /api/v1/users | ユーザー管理 |
| 2 | AuditSets | /api/v1/audit-sets | 監査セット |
| 3 | EventLogs | /api/v1/event-logs | イベントログ |

## 共通仕様

### リクエストヘッダー

| ヘッダー | 必須 | 説明 |
|---------|------|------|
| Authorization | Yes | Bearer {token} |
| Content-Type | Yes | application/json |
| Accept-Language | No | レスポンス言語 |
| X-Request-ID | No | リクエスト追跡ID |
| X-Transaction-Id | No* | 分散トランザクションID(2PC使用時必須) |

### ページネーション

```json
{
  "data": [...],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "totalItems": 100,
    "totalPages": 5
  }
}

クエリパラメータ

パラメータ説明例
pageページ番号?page=1
pageSize1ページの件数?pageSize=20
sortソート項目?sort=createdAt:desc
filterフィルタ条件?filter[status]=active

ScalarDB トランザクション例外のエラーコード

エラーコードScalarDB例外HTTPステータスリトライ
SCALARDB_001CrudConflictException409Yes (Exponential backoff)
SCALARDB_002CommitConflictException409Yes (Exponential backoff)
SCALARDB_003UnknownTransactionStatusException500Yes (べき等確認後)
SCALARDB_004CommitException500No
SCALARDB_005UnsatisfiedConditionException422No

CDCメタデータのフィルタリング

以下のカラムはAPIレスポンスから除外されます:

  • tx_state, tx_id, tx_prepared_at, tx_committed_at, tx_version
  • before_tx_id, before_state, before_version, before_prepared_at, before_committed_at

サービス間通信設計

分散トランザクションエンドポイント

POST /api/v1/{resource}/prepare

トランザクションの準備フェーズ

POST /api/v1/{resource}/commit

トランザクションのコミット

POST /api/v1/{resource}/rollback

トランザクションのロールバック

トランザクションIDの伝播

すべてのサービス間通信でX-Transaction-Idヘッダーを使用してトランザクションIDを伝播します。

エンドポイント詳細

GET /api/v1/users

説明: ユーザー一覧を取得

認可: ADMIN, MANAGER

クエリパラメータ:

パラメータ型必須説明
pageintegerNoページ番号 (default: 1)
pageSizeintegerNo件数 (default: 20, max: 100)
statusstringNoステータスフィルタ

レスポンス (200):

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "user@example.com",
      "name": "山田太郎",
      "status": "active",
      "createdAt": "2026-01-15T09:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "totalItems": 45,
    "totalPages": 3
  }
}

注意: tx_stateなどのCDCメタデータは除外されています。

エラーレスポンス例

409 Conflict(リトライ可能)

{
  "error": {
    "code": "SCALARDB_001",
    "message": "データ競合が発生しました。リトライしてください",
    "details": {
      "exception": "CrudConflictException",
      "retryable": true,
      "retryStrategy": "exponential_backoff",
      "recommendedWaitMs": 1000
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

422 Unprocessable Entity(リトライ不可)

{
  "error": {
    "code": "SCALARDB_005",
    "message": "更新条件が満たされていません",
    "details": {
      "exception": "UnsatisfiedConditionException",
      "retryable": false,
      "expectedCondition": {
        "field": "version",
        "expectedValue": 5,
        "actualValue": 6
      }
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

500 Internal Server Error(べき等確認後リトライ)

{
  "error": {
    "code": "SCALARDB_003",
    "message": "トランザクションの状態が不明です",
    "details": {
      "exception": "UnknownTransactionStatusException",
      "retryable": true,
      "retryStrategy": "idempotent_retry",
      "guidance": "操作がべき等であることを確認してからリトライしてください",
      "checkEndpoint": "/api/v1/transactions/{transactionId}/status"
    },
    "timestamp": "2026-02-17T10:00:00Z",
    "traceId": "abc-123-def"
  }
}

## API設計チェックリスト

### URL設計
- [ ] リソース名が複数形になっている
- [ ] URLにアクション動詞が含まれていない
- [ ] 一貫したケース規則(kebab-case)
- [ ] 適切な階層構造

### HTTPメソッド
- [ ] 適切なメソッドが使用されている
- [ ] べき等性が考慮されている
- [ ] 適切なステータスコードを返す

### リクエスト/レスポンス
- [ ] 一貫したJSON構造
- [ ] 適切なバリデーション
- [ ] ページネーションの実装
- [ ] 適切なエラーハンドリング
- [ ] CDCメタデータのフィルタリング

### ScalarDB固有
- [ ] トランザクション例外の適切なマッピング
- [ ] リトライ戦略の明示
- [ ] トランザクションIDの伝播(2PC使用時)
- [ ] べき等性の実装(分散トランザクション)

### セキュリティ
- [ ] 認証が必要なエンドポイントの保護
- [ ] 認可の実装
- [ ] 入力値のサニタイズ

## 使用例

Skill: api-design

プロジェクト名: scalar-auditor-for-box APIバージョン: v1 ベースURL: /api/v1 認証方式: Bearer (JWT)


## 注意事項

- 既存のAPIとの後方互換性を考慮する
- バージョニング戦略を事前に決定する
- APIドキュメントは常に最新に保つ
- セキュリティレビューを実施する
- ScalarDBのトランザクション例外を適切にHTTPステータスコードにマッピングする
- CDCメタデータは必ずAPIレスポンスから除外する
- 分散トランザクションではトランザクションIDを確実に伝播する
- べき等性を実装してリトライに対応する

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

ScalarDBを前提としたデータベース設計を行います。スキーマ設計、トランザクション設計、マルチストレージ構成を対話形式で決定し、スキーマファイルと設計書を生成します。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

DDDに基づいたドメインモデルを設計します。戦略的設計(境界コンテキスト、ユビキタス言語)と戦術的設計(エンティティ、値オブジェクト、集約、ドメインサービス、ドメインイベント)を定義し、ヘキサゴナルアーキテクチャとの統合を行います。ScalarDBのトランザクション境界や管理テーブル分類の考慮事項を含みます。中間状態はresearch/に記録されます。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

設計ドキュメントに基づいて実装計画を生成します。ScalarDB特有のスキーマ定義、トランザクション実装、統合テストを含む実装可能なタスク指示書を作成し、フェーズ別の実装ロードマップを提供します。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

Kubernetes、Kong API Gateway、ScalarDB Cluster v3.17を使用したインフラストラクチャ設計を行います。マニフェストファイルと設定ファイルを生成します。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

ScalarDBの制約を考慮したデータモデル設計を行います。Partition Key・Clustering Key・Secondary Index の設計、ホットスポット評価、メタデータオーバーヘッド見積もり、バックエンドDB選定を含みます。ワークフローStep 04(データモデル設計)で使用します。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

ScalarDBのトランザクション設計を行います。トランザクション境界定義、パターン選定(単一集約内/2PC/Saga/ハイブリッド)、OCC競合率評価、バッチ処理設計、v3.17最適化適用計画を含みます。ワークフローStep 05(トランザクション設計)で使用します。

The English summary is being prepared. Showing the original description.

wfukatsu/coding-agent-for-scalardb6Updated Feb 19, 2026

See all skills by wfukatsu

Report a problem with this skill