Skip to content
Published on

API設計 & マイクロサービスアーキテクチャ完全ガイド

Authors

目次

1. API設計原則

1.1 Richardson成熟度モデル

Leonard Richardsonが提唱したREST成熟度モデルは、APIのRESTful度合いを4段階で分類する。

レベル名前説明
Level 0The Swamp of POX単一URI、単一HTTPメソッド(通常POST)
Level 1Resources個別リソースURI使用、依然として単一メソッド
Level 2HTTP VerbsHTTPメソッドを適切に活用(GET、POST、PUT、DELETE)
Level 3Hypermedia ControlsHATEOAS - レスポンスに次のアクションリンクを含む

多くの実務APIはLevel 2を目標としており、Level 3(HATEOAS)は実装の複雑さに対して実質的なメリットが少ないため、選択的に適用される。

1.2 リソースネーミング規約

良いAPI設計の核心は、一貫したリソースネーミングである。

# 良い例
GET    /api/v1/users
GET    /api/v1/users/123
GET    /api/v1/users/123/orders
POST   /api/v1/users
PUT    /api/v1/users/123
DELETE /api/v1/users/123

# 悪い例
GET    /api/v1/getUsers
POST   /api/v1/createUser
GET    /api/v1/user_list

核心原則:

  • 名詞を使用: リソースは名詞で表現する(users、orders、products)
  • 複数形: コレクションは複数形を使用する(/users、/orders)
  • 小文字 + ハイフン: kebab-caseを使用する(/order-items)
  • 階層関係: ネストしたリソースで表現する(/users/123/orders)
  • フィルタリングはクエリパラメータ: /users?status=active&role=admin

1.3 HTTPメソッドとステータスコード

GET     - 取得(安全、冪等)
POST    - 作成(非安全、非冪等)
PUT     - 全体更新(非安全、冪等)
PATCH   - 部分更新(非安全、非冪等)
DELETE  - 削除(非安全、冪等)
OPTIONS - CORSプリフライト
HEAD    - ヘッダーのみ取得

主要ステータスコードガイド:

コード意味使用タイミング
200OK成功したGET、PUT、PATCH
201Created成功したPOST(Locationヘッダー含む)
204No Content成功したDELETE
400Bad Request不正なリクエスト形式
401Unauthorized認証失敗
403Forbidden権限なし
404Not Foundリソースなし
409Conflictリソース競合
422Unprocessable Entityバリデーション失敗
429Too Many RequestsRate Limit超過
500Internal Server Errorサーバーエラー

1.4 リクエスト/レスポンス設計

一貫したレスポンス形式は、クライアント開発体験を大幅に向上させる。

{
  "data": {
    "id": "user_123",
    "type": "user",
    "attributes": {
      "name": "田中太郎",
      "email": "tanaka@example.com",
      "created_at": "2026-04-12T10:00:00Z"
    }
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-04-12T10:00:00Z"
  }
}

ページネーションレスポンス:

{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 150,
    "total_pages": 8,
    "next_cursor": "eyJpZCI6MTAwfQ=="
  }
}

エラーレスポンス:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "リクエストデータが無効です",
    "details": [
      {
        "field": "email",
        "message": "正しいメール形式ではありません"
      }
    ]
  }
}

2. REST vs GraphQL vs gRPC 比較

2.1 比較表

特性RESTGraphQLgRPC
プロトコルHTTP/1.1HTTP/1.1HTTP/2
データ形式JSON/XMLJSONProtocol Buffers
スキーマOpenAPI(任意)SDL(必須).proto(必須)
型安全性弱い強い非常に強い
オーバー/アンダーフェッチあり解決解決
リアルタイムWebSocketSubscription双方向ストリーミング
ブラウザサポートネイティブネイティブgrpc-web必要
パフォーマンス普通普通高い
学習コスト低い中程度高い

2.2 各技術の適切な使用ケース

RESTが適している場合:

  • 公開API(Open API)
  • 単純なCRUD操作
  • キャッシングが重要な場合(HTTPキャッシング活用)
  • ブラウザから直接呼び出す場合

GraphQLが適している場合:

  • モバイルアプリ(帯域幅最適化)
  • 複雑なデータ関係がある場合
  • 異なるクライアントが異なるデータを要求する場合
  • 高速なフロントエンド開発サイクル

gRPCが適している場合:

  • マイクロサービス間の内部通信
  • 高いパフォーマンスが必要な場合
  • 双方向ストリーミングが必要な場合
  • 多言語環境

2.3 GraphQL例

# スキーマ定義
type User {
  id: ID!
  name: String!
  email: String!
  orders: [Order!]!
}

type Order {
  id: ID!
  total: Float!
  status: OrderStatus!
  items: [OrderItem!]!
}

type Query {
  user(id: ID!): User
  users(page: Int, limit: Int): [User!]!
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
}
# クライアントクエリ - 必要なフィールドのみリクエスト
query GetUserWithOrders {
  user(id: "123") {
    name
    email
    orders {
      id
      total
      status
    }
  }
}

2.4 gRPC例

syntax = "proto3";

package ecommerce;

service UserService {
  rpc GetUser (GetUserRequest) returns (UserResponse);
  rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
  rpc CreateUser (CreateUserRequest) returns (UserResponse);
}

message GetUserRequest {
  string user_id = 1;
}

message UserResponse {
  string id = 1;
  string name = 2;
  string email = 3;
  int64 created_at = 4;
}

message ListUsersRequest {
  int32 page = 1;
  int32 limit = 2;
}

message CreateUserRequest {
  string name = 1;
  string email = 2;
}

3. APIバージョニング

3.1 バージョニング戦略比較

戦略利点欠点
URIバージョニング/api/v1/users直感的、キャッシュ容易URI汚染
ヘッダーバージョニングAccept: application/vnd.api+json;version=1URIクリーンテスト困難
クエリバージョニング/api/users?version=1実装簡単キャッシュ複雑
Content NegotiationAccept: application/vnd.company.v1+json標準準拠複雑

URIバージョニングが最も広く使用されており、実用性と明確さの面で推奨される。

3.2 後方互換性維持の原則

後方互換可能な変更(非破壊的):
  - 新しいエンドポイントの追加
  - レスポンスへの新しいフィールドの追加
  - オプションのリクエストパラメータの追加
  - 新しいenum値の追加(クライアントがunknown処理する場合)

後方互換不可能な変更(破壊的):
  - 既存フィールドの削除またはリネーム
  - フィールド型の変更
  - 必須パラメータの追加
  - レスポンス構造の変更
  - URLパスの変更

3.3 API廃止戦略

Phase 1: Sunsetヘッダー追加
  Sunset: Sat, 01 Jan 2027 00:00:00 GMT
  Deprecation: true
  Link: <https://api.example.com/v2/docs>; rel="successor-version"

Phase 2: レスポンスに警告を含める(6ヶ月間)
Phase 3: Rate limitを段階的に縮小(3ヶ月間)
Phase 4: 410 Goneレスポンスを返す

4. 認証/認可 (Authentication / Authorization)

4.1 認証方式比較

方式セキュリティレベル使用ケース複雑度
API Key低い内部/パートナーAPI低い
OAuth 2.0高いユーザー認証委譲高い
JWT中程度ステートレス認証中程度
mTLS非常に高いサービス間通信高い

4.2 OAuth 2.0フロー

Authorization Code Flow(サーバーサイドアプリ推奨):

1. クライアント --> 認可サーバー: 認可コードリクエスト
   GET /authorize?response_type=code
     &client_id=CLIENT_ID
     &redirect_uri=CALLBACK_URL
     &scope=read:user
     &state=RANDOM_STATE

2. ユーザー --> 認可サーバー: ログインおよび権限同意

3. 認可サーバー --> クライアント: 認可コード返却
   302 Redirect: CALLBACK_URL?code=AUTH_CODE&state=RANDOM_STATE

4. クライアント --> 認可サーバー: トークン交換
   POST /token
     grant_type=authorization_code
     &code=AUTH_CODE
     &client_id=CLIENT_ID
     &client_secret=CLIENT_SECRET

5. 認可サーバー --> クライアント: アクセストークン + リフレッシュトークン

4.3 JWT構造とセキュリティ

{
  "header": {
    "alg": "RS256",
    "typ": "JWT",
    "kid": "key-id-001"
  },
  "payload": {
    "sub": "user_123",
    "iss": "auth.example.com",
    "aud": "api.example.com",
    "exp": 1744540800,
    "iat": 1744537200,
    "scope": "read:users write:orders",
    "roles": ["admin"]
  }
}

JWTセキュリティチェックリスト:

  • RS256(非対称)アルゴリズムの使用を推奨(HS256より安全)
  • 短い有効期限の設定(15分以下)
  • リフレッシュトークンはサーバーサイドに保存
  • iss、aud、expクレームを必ず検証
  • noneアルゴリズムを拒否
  • kid(Key ID)検証でキー混同攻撃を防止

4.4 mTLS(相互TLS)

サービス間通信セキュリティ:

1. 各サービスに固有のX.509証明書を発行
2. 通信時に双方向の証明書検証
3. 証明書の自動更新(cert-managerなど)

メリット:
  - サービスIDを暗号学的に証明
  - ネットワークレベルでの暗号化
  - Zero Trustアーキテクチャの基盤

デメリット:
  - 証明書管理の複雑さ
  - 証明書期限切れ時のサービス停止リスク
  - デバッグの困難さ

5. Rate Limiting

5.1 アルゴリズム比較

Token Bucket:

原理: 一定速度でトークンが追加され、リクエスト時にトークンを消費
メリット: バーストトラフィックを許容しつつ平均速度を維持
デメリット: メモリ使用

例:
  - バケットサイズ: 100トークン
  - 補充速度: 10トークン/秒
  - リクエストごとに1トークン消費
  - バースト: 最大100リクエスト同時可能

Sliding Window:

原理: 時間ウィンドウ内のリクエスト数をカウント
メリット: 正確な制限、ウィンドウ境界問題を解決
デメリット: 前のウィンドウカウンターの保存が必要

例:
  現在時刻: 12:01:30
  前のウィンドウ (12:00-12:01): 80リクエスト
  現在のウィンドウ (12:01-12:02): 20リクエスト
  加重合計: 80 * 0.5 + 20 = 60(上限100以内)

5.2 Rate Limitレスポンスヘッダー

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1744540860
Retry-After: 60

5.3 API Gatewayを用いたRate Limiting

# Kong Gateway設定例
plugins:
  - name: rate-limiting
    config:
      minute: 100
      hour: 1000
      policy: redis
      redis_host: redis-cluster
      redis_port: 6379
      fault_tolerant: true
      hide_client_headers: false

6. マイクロサービスパターン

6.1 サービス分割基準 - DDD Bounded Context

Eコマースドメイン分析:

[注文コンテキスト]          [商品コンテキスト]
  - Order                   - Product
  - OrderItem               - Category
  - OrderStatus             - Inventory
  - Payment                 - Price

[ユーザーコンテキスト]      [配送コンテキスト]
  - User                    - Shipment
  - Address                 - Tracking
  - Authentication          - Carrier
  - Profile                 - Delivery

[通知コンテキスト]          [検索コンテキスト]
  - Notification            - SearchIndex
  - Template                - Filter
  - Channel                 - Ranking

分割原則:

  • ビジネスケイパビリティ基準で分割
  • データオーナーシップ: 各サービスが自身のデータベースを所有
  • チーム自律性: ツーピザチームルール(6-8人)
  • デプロイ独立性: 他サービスの変更なしにデプロイ可能
  • 疎結合、高凝集

6.2 サービス通信 - 同期 vs 非同期

同期通信(Request-Response):

  [API Gateway] --> [Order Service] --> [Payment Service]
                                    --> [Inventory Service]

  メリット: 即時レスポンス、実装が簡単
  デメリット: 強い結合、連鎖障害、レイテンシ累積

非同期通信(Event-Driven):

  [Order Service] --> [Message Broker] --> [Payment Service]
                                       --> [Inventory Service]
                                       --> [Notification Service]

  メリット: 疎結合、高い復元力、スケーラビリティ
  デメリット: 最終的な整合性、デバッグの困難さ

Kafka vs RabbitMQ比較:

特性Apache KafkaRabbitMQ
モデルPub/Sub + LogQueue + Exchange
順序保証パーティション内で保証キュー内で保証
スループット非常に高い(数百万/秒)高い(数万/秒)
メッセージ保持設定期間中保持消費後削除
再処理オフセットリセットで可能不可能(DLQ使用)
使用ケースイベントストリーミング、ログタスクキュー、RPC

6.3 API Gatewayパターン

役割:
  - リクエストルーティング
  - 認証/認可
  - Rate Limiting
  - ロードバランシング
  - リクエスト/レスポンス変換
  - サーキットブレイカー
  - モニタリング/ロギング

主要ソリューション:
  - Kong: オープンソース、プラグインエコシステム
  - Envoy: 高性能、L7プロキシ
  - AWS API Gateway: マネージド、サーバーレス
  - NGINX: 軽量、高パフォーマンス
  - Traefik: 自動サービスディスカバリ
# Envoyルーティング設定例
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8080
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                route_config:
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match:
                            prefix: "/api/v1/users"
                          route:
                            cluster: user_service
                        - match:
                            prefix: "/api/v1/orders"
                          route:
                            cluster: order_service

6.4 サービスディスカバリ

クライアントサイドディスカバリ:
  1. サービスA --> サービスレジストリ: サービスBのアドレスを検索
  2. サービスA --> サービスB: 直接呼び出し
  ツール: Eureka、Consul

サーバーサイドディスカバリ:
  1. サービスA --> ロードバランサー: リクエスト
  2. ロードバランサー --> サービスレジストリ: アドレス検索
  3. ロードバランサー --> サービスB: 転送
  ツール: K8s Service + DNS、AWS ALB

Kubernetes DNSベース:
  サービス内部DNS: service-name.namespace.svc.cluster.local
  例: order-service.production.svc.cluster.local

6.5 Circuit Breakerパターン

状態遷移:

  [Closed] --失敗閾値超過--> [Open]
  [Open]   --タイムアウト経過--> [Half-Open]
  [Half-Open] --成功--> [Closed]
  [Half-Open] --失敗--> [Open]
// Resilience4j設定例
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
    .failureRateThreshold(50)        // 50%失敗でOpen
    .waitDurationInOpenState(
        Duration.ofSeconds(30))       // 30秒後にHalf-Open
    .slidingWindowSize(10)            // 直近10リクエスト基準
    .minimumNumberOfCalls(5)          // 最低5回呼び出し後に判断
    .permittedNumberOfCallsInHalfOpenState(3)
    .build();

CircuitBreaker circuitBreaker = CircuitBreaker.of(
    "paymentService", config);

Supplier<PaymentResponse> decoratedSupplier =
    CircuitBreaker.decorateSupplier(
        circuitBreaker,
        () -> paymentService.processPayment(request)
    );

フォールバック戦略:

  • キャッシュされたレスポンスを返す: 前回の成功レスポンスを使用
  • デフォルト値を返す: 事前定義されたデフォルトレスポンス
  • 代替サービスを呼び出す: バックアップサービスを使用
  • グレースフルデグラデーション: 機能縮小レスポンス

7. サービスメッシュ

7.1 サービスメッシュとは?

サービスメッシュアーキテクチャ:

  [Service A] <--> [Sidecar Proxy] <--> [Sidecar Proxy] <--> [Service B]
                          |                      |
                          v                      v
                   [Control Plane (Istio/Linkerd)]
                          |
                   [設定、ポリシー、証明書管理]

サイドカープロキシの役割:
  - トラフィックルーティングとロードバランシング
  - mTLS暗号化
  - サーキットブレイカー
  - リトライとタイムアウト
  - メトリクス収集
  - 分散トレーシング

7.2 Istio vs Linkerd

特性IstioLinkerd
データプレーンEnvoylinkerd2-proxy (Rust)
リソース使用量高い低い
機能非常に豊富コア機能に集中
学習コスト急勾配なだらか
コミュニティGoogle主導CNCF Graduated
マルチクラスタサポートサポート

7.3 Istioトラフィック管理

# カナリアデプロイメント - トラフィック分割
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
    - order-service
  http:
    - route:
        - destination:
            host: order-service
            subset: v1
          weight: 90
        - destination:
            host: order-service
            subset: v2
          weight: 10
      retries:
        attempts: 3
        perTryTimeout: 2s
        retryOn: 5xx,reset,connect-failure
      timeout: 10s
# サーキットブレイカー設定
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        h2UpgradePolicy: DEFAULT
        http1MaxPendingRequests: 100
        http2MaxRequests: 1000
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50

8. イベント駆動アーキテクチャ

8.1 Event Sourcing

従来の方式: 現在の状態のみ保存
  ordersテーブル: id=1, status=SHIPPED, total=50000

Event Sourcing: すべての状態変更をイベントとして保存
  eventsテーブル:
    1. OrderCreated     (total=50000)
    2. PaymentReceived  (amount=50000)
    3. OrderConfirmed   ()
    4. ItemShipped       (tracking=KR123456)

メリット:
  - 完全な監査ログ
  - タイムトラベル(特定時点の状態を再現)
  - イベントリプレイで新しいビューを生成
  - デバッグが容易

デメリット:
  - イベントスキーマの進化管理
  - イベントストアのサイズ増大
  - 最終的な整合性(Eventual Consistency)

8.2 CQRS (Command Query Responsibility Segregation)

CQRSアーキテクチャ:

  [Command] --> [Write Model] --> [Event Store]
                                       |
                                  [Event Bus]
                                       |
                              [Read Modelプロジェクション]
                                       |
                                [Query] <-- [Read DB]

Command(書き込み):
  - ドメインロジック実行
  - イベント発行
  - 正規化されたデータベース

Query(読み取り):
  - 非正規化された読み取り専用ビュー
  - 高速クエリに最適化
  - 多様なストレージ使用可能(ES、Redisなど)

8.3 Sagaパターン - 分散トランザクション

マイクロサービス環境では、2PC(Two-Phase Commit)にはパフォーマンスと可用性の問題がある。Sagaパターンは、ローカルトランザクションのシーケンスで分散トランザクションを管理する。

Choreography(振付)方式:

注文作成Saga:

  [Order Service]       [Payment Service]    [Inventory Service]
       |                      |                     |
  OrderCreated -------->      |                     |
       |              PaymentProcessed -------->    |
       |                      |              InventoryReserved
       |                      |                     |
       |              <--- (成功時) --->             |
  OrderConfirmed              |                     |

補償トランザクション(失敗時):
  InventoryReserveFailed --> PaymentRefunded --> OrderCancelled

Orchestration(オーケストレーション)方式:

  [Order Saga Orchestrator]
       |
       |--> 1. Order Service: 注文作成
       |--> 2. Payment Service: 決済処理
       |--> 3. Inventory Service: 在庫予約
       |--> 4. Shipping Service: 配送作成
       |
  (失敗時は逆順で補償)
       |--> 3c. Inventory: 在庫解放
       |--> 2c. Payment: 返金処理
       |--> 1c. Order: 注文取消

9. 分散トレーシング

9.1 Correlation IDパターン

リクエストフロー:

  [Client]
    X-Request-ID: req-abc-123
       |
  [API Gateway]
    X-Request-ID: req-abc-123
    X-Correlation-ID: corr-xyz-789
       |
  [Order Service] ----------> [Payment Service]
    trace_id: corr-xyz-789     trace_id: corr-xyz-789
    span_id: span-001          span_id: span-002
    parent_span_id: null        parent_span_id: span-001
       |
       ----------> [Inventory Service]
                    trace_id: corr-xyz-789
                    span_id: span-003
                    parent_span_id: span-001

9.2 OpenTelemetry導入

// OpenTelemetry SDK初期化
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'http://otel-collector:4317',
  }),
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});

sdk.start();
// 手動スパン作成
import { trace, SpanStatusCode } from '@opentelemetry/api';

const tracer = trace.getTracer('order-service');

async function processOrder(orderId: string) {
  const span = tracer.startSpan('processOrder', {
    attributes: {
      'order.id': orderId,
      'service.name': 'order-service',
    },
  });

  try {
    span.addEvent('Validating order');
    await validateOrder(orderId);

    span.addEvent('Processing payment');
    await processPayment(orderId);

    span.setStatus({ code: SpanStatusCode.OK });
  } catch (error) {
    span.setStatus({
      code: SpanStatusCode.ERROR,
      message: String(error),
    });
    throw error;
  } finally {
    span.end();
  }
}

9.3 オブザーバビリティの3本柱

1. ログ(Logs):
   - 構造化ログ(JSON)
   - ログレベル(DEBUG、INFO、WARN、ERROR)
   - Correlation IDを含める
   - ELK Stack / Loki

2. メトリクス(Metrics):
   - REDメトリクス: Rate、Errors、Duration
   - USEメトリクス: Utilization、Saturation、Errors
   - Prometheus + Grafana

3. トレース(Traces):
   - 分散リクエスト追跡
   - スパン(Span)ベースの可視化
   - Jaeger / Zipkin / Tempo

10. 実践: Eコマースシステム MSA設計

10.1 全体アーキテクチャ

                    [CDN / CloudFront]
                           |
                    [API Gateway (Kong)]
                     /    |    |     \
                    /     |    |      \
  [User Service] [Product] [Order] [Payment]
       |          Service   Service   Service
       |            |         |         |
  [User DB]    [Product DB] [Order DB] [Payment DB]
  (PostgreSQL)  (PostgreSQL) (PostgreSQL) (PostgreSQL)
                    |         |
              [Search Service] [Notification]
                    |           Service
              [Elasticsearch]     |
                              [Kafka]
                                |
                         [Email/SMS/Push]

10.2 サービスごとの技術スタック

User Service:
  - 言語: Go
  - DB: PostgreSQL
  - キャッシュ: Redis(セッション)
  - 通信: REST + gRPC

Product Service:
  - 言語: Java (Spring Boot)
  - DB: PostgreSQL
  - キャッシュ: Redis(商品情報)
  - 検索: Elasticsearch
  - 通信: REST + gRPC

Order Service:
  - 言語: Java (Spring Boot)
  - DB: PostgreSQL
  - メッセージング: Kafka(注文イベント)
  - 通信: gRPC + Kafka

Payment Service:
  - 言語: Go
  - DB: PostgreSQL
  - 外部: 決済ゲートウェイ連携
  - 通信: gRPC

Notification Service:
  - 言語: Node.js
  - DB: MongoDB(テンプレート)
  - メッセージング: Kafka Consumer
  - 外部: SendGrid、Firebase

10.3 注文処理フロー

1. クライアント --> API Gateway: POST /api/v1/orders
2. API Gateway --> Order Service: 注文作成リクエスト
3. Order Service --> Product Service (gRPC): 在庫確認
4. Order Service --> Kafka: OrderCreatedイベント発行
5. Payment Service (Consumer): 決済処理
6. Payment Service --> Kafka: PaymentCompletedイベント
7. Order Service (Consumer): 注文ステータス更新
8. Notification Service (Consumer): 注文確認メール送信
9. Product Service (Consumer): 在庫差し引き

10.4 障害対応戦略

Circuit Breaker:
  - Paymentサービス障害時は注文受付のみ進行
  - 決済はKafkaキューに積載後に再処理

Retry + Exponential Backoff:
  - 1回目リトライ: 100ms
  - 2回目リトライ: 200ms
  - 3回目リトライ: 400ms
  - 最大リトライ: 5回

Bulkheadパターン:
  - サービスごとにスレッドプールを隔離
  - 1つのサービス障害が全体に波及しないように隔離

Dead Letter Queue:
  - 処理失敗メッセージをDLQに移動
  - 手動分析および再処理
  - アラート設定で運用チームに通知

10.5 デプロイ戦略

# Kubernetes Deployment - カナリアデプロイメント
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-canary
  labels:
    app: order-service
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: order-service
      version: v2
  template:
    metadata:
      labels:
        app: order-service
        version: v2
    spec:
      containers:
        - name: order-service
          image: order-service:2.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10

まとめ

API設計とマイクロサービスアーキテクチャは、現代のソフトウェア開発における核心的な能力である。重要なポイントをまとめると以下の通りだ。

  1. API設計は契約である - 一貫したネーミング、適切なステータスコード、明確なエラーメッセージが開発生産性を決定する
  2. 技術選択はコンテキスト次第 - REST、GraphQL、gRPCそれぞれの強みが異なり、混用が一般的である
  3. セキュリティは最初から - 認証/認可、mTLS、Rate Limitingは後回しにせず設計段階から考慮すべきだ
  4. サービス分割は慎重に - DDD Bounded Contextに基づき、小さすぎず大きすぎないように分割する
  5. 障害は必ず起きる - Circuit Breaker、Retry、Bulkhead、Sagaパターンで復元力を確保する
  6. オブザーバビリティこそ運用力 - ログ、メトリクス、トレースの3要素を統合して問題を迅速に把握する

モノリスから始めて、実際の必要性に応じて段階的にマイクロサービスを導入するのが最も賢明なアプローチである。技術的な優雅さよりもビジネス価値の提供に集中しよう。