コンテンツにスキップ
検索語を入力してください

    サービス境界

    サービス間の Protobuf やイベントは、プロセス内の TryFrom よりスキーマ進化と冪等性の問題が前面に出る。破壊的変更や未知バージョンでパニックするコンシューマは、本番で連鎖障害になる。

    境界パースの基本は 境界防御、イベントの保存と重複排除は 永続化、集約、イベント、ストリーム側の処理は ストリームと継続クエリ を参照する。

    リモートサービスも外部境界として扱う

    Section titled “リモートサービスも外部境界として扱う”

    マイクロサービス境界は DTO 境界である。モノリス内の HTTP handler や queue consumer と同様、ワイヤメッセージを TryFrom でドメインコマンドまたは integration event に変換する。

    Protobuf/JSON message -> integration DTO -> TryFrom -> domain command or event

    他サービスの生成 protobuf 型をドメイン crate に import しない。生成 client/server は infrastructure または専用 *-api crate に置き、adapter 境界でドメイン型にマップする。

    producer と consumer は独立デプロイを前提とする。永続化またはキューされる protobuf メッセージには明示的互換ポリシーが必要。

    変更互換性推奨アプローチ
    optional フィールド追加後方互換default 付き新フィールド。consumer は未知フィールドを無視
    oneof variant 追加注意付き前方互換メッセージ version を上げる。旧 consumer は未知 variant をスキップ
    フィールド renameワイヤ上 breakingフィールド番号を rename しない。新フィールド追加と旧 deprecate
    フィールド型変更breaking新メッセージ型または envelope の新 version
    フィールド削除deprecate 後 breaking番号を reserve。移行中は dual-read

    サービス境界を越える event には version 付き envelope で payload を包む:

    pub struct IntegrationEventEnvelope {
    pub event_type: EventTypeName,
    pub schema_version: u32,
    pub payload: prost::bytes::Bytes,
    }

    consumer は:

    1. event_typeschema_version でルーティング
    2. version 固有 DTO にデシリアライズ
    3. DTO -> ドメイン integration event を TryFrom で変換
    4. panic せず未知 version を dead-letter または metric でカウント

    メッセージキューと非同期統合

    Section titled “メッセージキューと非同期統合”

    queue consumer は at-least-once 配送を継承する。handler は冪等でなければならず、broker 契約が保証しない限りパーティション間の順序を仮定しない。

    pub async fn handle_delivery(
    message: QueueMessageDto,
    ) -> Result<(), HandlerError> {
    let command = AssignDriverCommand::try_from(message.payload)?;
    if self.processed.exists(&command.idempotency_key).await? {
    return Ok(());
    }
    self.use_case.execute(command).await?;
    self.processed.record(command.idempotency_key).await?;
    Ok(())
    }

    可能なら idempotency key を副作用と同じ store に永続化。outbox 公開は 永続化、集約、イベント に合わせる。

    サーキットブレーカー、タイムアウト、リトライ、レート制限はインフラ adapter に属する — ドメイン遷移やユースケースのビジネスルールではない。

    ControlWhereDomain impact
    TimeoutgRPC/HTTP client builder型付き ClientError::Timeout にマップ
    Retry with backoff外部 API を呼ぶ adapter冪等 read または明示 keyed write のみリトライ
    Circuit breakertower / client middlewareユースケースへ ClientError::Unavailable
    Rate limitgateway または outbound clientClientError::RateLimited にマップ。ドメインで spin しない
    let response = self
    .billing_client
    .charge(request)
    .await
    .map_err(|e| match e {
    BillingClientError::Timeout => AssignDriverError::BillingTimeout,
    BillingClientError::Unavailable => AssignDriverError::BillingUnavailable,
    other => AssignDriverError::Billing(other),
    })?;

    ユースケースが失敗をリトライ可能か補償か決める。adapter がポリシーを実行する。

    outbound 呼び出しと queue メッセージに correlation_idtrace_id、テナントコンテキストを伝播する。ingress adapter の tracing span に設定し、metadata header または message 属性に注入する。

    分散 trace をドメイン監査ログと混同しない。耐久性が必要なら outbox 経由でビジネス event を永続化(ロギングとメトリクス 参照)。

    2 サービスが protobuf または JSON スキーマを共有するとき:

    • 生成 Rust 型を CI に check-in するか、専用 job で再生成
    • リリース前に consumer-driven 契約テストまたは .proto の breaking 変更検出を実行
    • 各サポート schema_version の fixture メッセージをテストに保持

    Cargo.tomltonicprostlapinrdkafkaaws-sdk-sqs などがあるとき、このガイドを 境界防御 と consumer/projection 向け ストリームと継続クエリ と一緒に読み込む。

    レビューでは、TryFrom なしのワイヤデータ直渡し、ドメインへの prost 型 import、破壊的スキーマ変更、非冪等コンシューマ、ドメイン内のリトライ / サーキットブレーカ、相関 ID の欠落を指摘する。

    protobuf / JSON スキーマ進化は明示的か — High

    Section titled “protobuf / JSON スキーマ進化は明示的か — High”

    破壊的なフィールド改名 / 削除、schema_version の欠落、未知のイベント型やバージョンでパニックするコンシューマを指摘する。

    キューハンドラは冪等か — High

    Section titled “キューハンドラは冪等か — High”

    永続化、集約、イベント も照合する。冪等キーや重複排除ストレージなしに副作用を適用するコンシューマを指摘する。

    ワイヤメッセージは DTO → ドメインで変換されているか — High

    Section titled “ワイヤメッセージは DTO → ドメインで変換されているか — High”

    TryFrom 検証なしに protobuf、JSON、キューペイロードをドメインロジックへ直接渡すハンドラを指摘する。

    リトライ、ブレーカ、レート制限はアダプタにあるか — Medium

    Section titled “リトライ、ブレーカ、レート制限はアダプタにあるか — Medium”

    ドメイン遷移やユースケースのビジネスルール内のリトライループ、サーキットブレーカ状態、レート制限を指摘する。

    生成クライアント型はドメインクレートに漏れていないか — Medium

    Section titled “生成クライアント型はドメインクレートに漏れていないか — Medium”

    アダプタ境界でマッピングするのではなく、ドメインやユースケースモジュールが tonic / prost 生成型を import している場合は指摘する。

    相関コンテキストは外向き呼び出しで伝播されているか — Low

    Section titled “相関コンテキストは外向き呼び出しで伝播されているか — Low”

    入口リクエストが既に correlation_id やトレースコンテキストを運んでいるのに、サービス間呼び出しや公開メッセージからそれらを欠落させる場合は指摘する。