Communityコーディング&開発github.com

swift-microservices/swift-microservices-architect

Swiftサーバーバックエンドを、Hummingbirdゲートウェイの背後にあるgRPCマイクロサービスとしてアーキテクチャ設計します。各サービスは1つのSwiftパッケージ、型付きthrowsのユースケースからなるCore、テクノロジーごとのアダプターターゲット(Postgres(行レベルセキュリティ)、gRPC、Temporal、Valkey)、そして実行可能なコンポジションルートを持ちます。Swiftバックエンドの計画立案やサービス分割、モジュール境界の設計、Package.swiftの作成、サービス・エンドポイント・ユースケース・リポジトリ・マイグレーション・マルチテナントテーブル・耐久性のあるTemporalワークフローの追加、設定やグレースフルシャットダウン・mTLS・JWT認証の配線、サーバータイプやターゲットの命名、GitHub Actions上のCI/CDのセットアップ、Swiftサーバーのアーキテクチャやコードスタイルのレビュー(ユーザーがアーキテクチャを明示しなくても)に使用します。

swift-microservices-architect とは?

このスキルは、SwiftサーバーバックエンドをgRPCマイクロサービスアーキテクチャとして設計・実装するための包括的なガイドです。Hummingbirdをゲートウェイとし、各サービスは独自のパッケージ(例: bookshelf-identity, bookshelf-catalog)で構成され、型付きthrowsのユースケースを含むCore、Postgres(行レベルセキュリティ)、gRPC、Temporal、Valkeyなどのテクノロジーごとのアダプターターゲット、そして実行可能なコンポジションルートを持ちます。Claude CodeやCursorなどのAIエージェントプラットフォームで使用でき、バックエンドの計画、サービスの追加、操作の追加、耐久性のあるプロセスの追加、CI/CDのセットアップ、アーキテクチャレビューといった具体的なタスクをチェックリストに沿って実行します。このスキルは、厳格なモジュール境界(Coreはドライバやトランスポートをインポートしない、アダプターターゲットは互いにインポートしないなど)、コードスタイル(AppleのWWDCサンプルコードを基準とした、エラーマッピング、ビルド→コールの原則、Swift 6モード)、およびセキュリティモデル(mTLS、JWT認証、行レベルセキュリティによるテナント分離)を強制します。これにより、保守性が高く、セキュアで、拡張可能なSwiftサーバーバックエンドを構築できます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/swift-microservices/swift-microservices-architect-skill/tree/HEAD/skills/swift-microservices-architect

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Swift マイクロサービスアーキテクト

別の方法で構築されたバックエンドでは、ユーザーが変更を求めない限りその構造と慣習を維持し、バックエンドに欠けているものに対してのみこのスキルから形を借りてください。

Xはターゲット名(LoansCore)や型の命名(BorrowBookUseCase、LoanService)におけるサービスを表し、<Org>と<org>は組織を表します。例として、小規模な貸出図書館であるBookshelfを示します:

パッケージ保持するもの
bookshelf-identityアカウント、パスワード、セッション; すべてのアクセストークンを発行; Valkeyにリセットコードを保存; 内部的に他のサービスのためのメンバー情報
bookshelf-catalog書籍: 誰でも閲覧可能、管理者のみ編集; Loansは内部で書籍を検索
bookshelf-loansメンバーの貸出、テナントテーブル; ワークフローが貸出を延滞としてマークし通知を送信
bookshelf-gateway公開HTTP API、サービスのgRPCコントラクトに転送
bookshelf-coreBookshelfAuthentication、BookshelfPersistence、BookshelfTransport、BookshelfTesting
bookshelf-protosIdentityProtos、CatalogProtos、LoansProtos

形状

クライアント ── HTTPS ──► エッジ (TLS終端) ── HTTP ──► ゲートウェイ (Hummingbird, OpenAPI)
ゲートウェイ ── gRPC, mTLS, 呼び出し元のJWT ──► 各サービスの XService
サービス、ワーカー ── gRPC, mTLS ──► 別のサービスの XInternalService
サービス、ワーカー ── mTLS ──► Temporal          サービス ──► 自身のPostgresデータベース、Valkey

すべてのサービスとゲートウェイは、<org>-core、<org>-protos、およびswift-microservicesライブラリ(スタック)に依存します。

サービスのパッケージ

<org>-x
├── XCore         ドメインモデル、エラー、リポジトリプロトコルとコマンド、ポート、ユースケース
├── XPostgres     データベースロールごとのスコープ、リポジトリ、ステートメント、マイグレーション
├── XGRPC         XService と XInternalService、Protobuf変換、Coreのポート向けgRPCクライアント
├── XTemporal     ワークフロー、アクティビティコンテナ、Coreのワークフローポート向けTemporalクライアント
├── XValkey       短期間の値のためのリポジトリ
├── X<Provider>   Coreポートの背後にあるサードパーティAPI(LoansResend)
└── X             実行ファイル: コマンド、設定デフォルト、マイグレーション、コンポジションルート

サービスは必要なターゲットのみを持ち、各ターゲットはその行にリストされたものだけをインポートします。厳格なルール:

  • XCoreはドライバ、トランスポート、コントラクト、ワークフローエンジン、設定、ライフサイクルモジュールをインポートしません(Coreがリンクしてもよいものを参照)。
  • アダプターターゲットは互いにインポートしません。実行ファイルがCoreのプロトコルを介して一方を他方に渡します。
  • 生成されたコントラクト型は、XGRPC、ゲートウェイのHTTPターゲット、および実行ファイルの外に出ません。
  • 実行ファイルのみが設定を読み取り、クライアントを構築し、ServiceGroupを実行します。
  • どのサービスも他のサービスのデータベースを読み取りません。データはコントラクトを介してのみサービス間を移動します。

誰が何を所有するか

関心事所有者
ビジネスルール、認可決定、エラーの意味XCoreのユースケース; アダプターは変換と委譲のみを行う
サービスが別のサービスのデータについて知っていることXCore Ports/ のモデル、それを返すポートの隣
Protobuf ↔ ドメイン、HTTP ↔ ProtobufXGRPCの Protobuf/ 変換; ゲートウェイの Schemas/
プロセス間のメッセージ; 公開API<org>-protos; ゲートウェイの openapi.yaml
呼び出し元の識別ゲートウェイがトークンを検証して転送; 各サービスが再度検証
内部RPCを呼び出せるプロセスリスナーのmTLS: 環境の認証局が署名するすべてのプロセス
テナント分離行レベルセキュリティ; <Org>Persistenceが呼び出し元を各トランザクションにバインドし、各オーディエンスのユースケースはそのデータベースロールとして実行
耐久性のある、遅延された、またはマルチサービスの作業XTemporalのTemporalワークフロー
すべてのサービスが同一に必要とするもの<org>-core: アイデンティティ、テナントバインディング、トランスポートリーダー

コードスタイル

コードは実装する要件のように読み取れ、AppleのWWDCサンプルコードを基準とします(スタイル)。ユースケースとアダプターは次のようにエラーをマッピングします:

do {
    …  // 作業、要件が述べる順序で
} catch let error as BorrowBookUseCaseError {
    throw error
} catch CatalogClientError.unavailable {
    logger.warning("貸出失敗: カタログが利用できません")
    throw .catalogUnavailable
} catch {
    logger.error("貸出失敗: 不明なエラー", metadata: ["error": "\(String(reflecting: error))"])
    throw .unknown
}
  • 1つのdoがreturnまで作業を保持し、各catchは自身のパスを終了します: catchが埋めるためにdoの前に何も宣言してはいけません。
  • 構築してから呼び出す: 呼び出しが受け取る値は名前付きのletであり、引数に変換、try、awaitを決して含めません(構築してから呼び出す)。
  • ユースケース、ワークフロー、アクティビティにヘルパーメソッドはなく、Resultの操作、制御フラグ、try?、catch内のネストしたdo、強制アンラップもありません。
  • Swift 6モードでExistentialAny、MemberImportVisibility、InternalImportsByDefault、NonisolatedNonsendingByDefault(Swift設定); サービスのターゲット間でのpackageアクセス。
  • 境界を越えるものはすべてSendable; Task {}やTask.detachedはなく、チェックされていない並行性は並行性が許可する場合のみ。

注意点

  • ServiceGroupから除外されたコンポーネントは決して実行されません: 実行されないGRPCClientやPostgresClientは接続しないため、その呼び出しはデッドラインまで待機します。
  • データベースオーナーとして接続されたプロセスは行レベルセキュリティをバイパスするため、すべてのプロセスはそのロールとして接続し、serve --migrate-databaseのみがオーナーとして実行されます。
  • TemporalはCodableを実行時にのみチェックします: すべてのワークフローとアクティビティのペイロード、およびそれが保持する各型はCodable, Sendableでなければなりません(ワークフロー)。
  • ワークフローコードはリプレイされます: ワークフロー内のDate.now、UUID()、ランダム性、Task.sleep、またはI/Oはそれを壊します(決定論)。
  • 所有コード内のプレーンまたはスコープ付きのimport FoundationはLinux上で完全なFoundationをリンクします; 条件付きのFoundationEssentialsインポートを使用してください。

チェックリスト

タスクのチェックリストを応答にコピーし、項目が完了したらチェックを入れます; 名前が挙げられた各.mdファイルはreferences/にあります。

バックエンドを計画する

- [ ] 機能と各機能が所有するデータ; 機能ごとにサービス(system.md#splitting-a-system-into-services)
- [ ] 各サービスに名前を付け; ターゲット名をグラフ内のすべてのモジュールと照合する
- [ ] サービスごと: オーディエンス別のXService RPC、XInternalService RPCと呼び出し元(コールサイクルなし)、テーブル(テナントかどうか)、ワークフロー、短期状態
- [ ] サービスごと: そのターゲット、コマンド、データベースロール
- [ ] <org>-coreのプロダクト、<org>-protosのコントラクト、階層別のゲートウェイルート
- [ ] ビルド順序: <org>-coreと<org>-protos、トークン発行者、各サービス(その呼び出し元の前)、ゲートウェイ
- [ ] system.md#the-planから計画を書く; コードの前にハードルールに対してチェックする

サービスを追加する

- [ ] <org>-protos: XProtos(XService付き)、およびプロセスが内部から呼び出す場合はXInternalService
- [ ] packages.md#packageswift-templateからパッケージ<org>-xを作成、計画が名前を挙げたターゲットのみで
- [ ] XCore: モデル、エラー、リポジトリ、ポート、RPCごとのユースケース(use-cases.md)
- [ ] XPostgres: ロール、テーブル、行レベルセキュリティ、ステートメント、ロールごとのスコープ(persistence.md)
- [ ] XGRPC: ユースケース上のprotoサービス、変換、ポート用クライアント(grpc.md)
- [ ] XTemporal、XValkey、X<Provider>(計画に応じて)
- [ ] X: コマンド、InMemoryProviderデフォルト、マイグレーション、Serve、およびワーカー付きRun(composition.md)
- [ ] ゲートウェイ: 公開RPC用のルート(gateway.md)
- [ ] モジュールごとにモックを使ったテストターゲット(testing.md)
- [ ] そのCIワークフロー、Containerfile、Dependabot(サービスとして)(delivery.md)
- [ ] swift build と swift test; 修正して繰り返し、両者が警告なしでパスするまで

操作を追加する

- [ ] コントラクト: XServiceのオーディエンス下のRPC、またはXInternalService内
- [ ] XCore: ユースケースの5つのファイル; そのスコープは触れるものだけをリストする(use-cases.md)
- [ ] XPostgres: 実行される可能性のあるロールのスコープがそのスコーププロトコルを採用
- [ ] XGRPC: ハンドラーと入力の変換、すべてのエラーケースがマッピングされている
- [ ] 実行ファイル: ユースケースをそのロールのデータベース上で、サービスに渡す
- [ ] ゲートウェイ: 階層内のルート(公開の場合)
- [ ] テスト: ユースケースの結果とハンドラーのステータス、モックを使って
- [ ] swift build と swift test; 修正して繰り返し、両者が警告なしでパスするまで

耐久性のあるプロセスを追加する

- [ ] XCore: XWorkflowClientポート; アクティビティが実行するユースケース(ワーカースコープによって採用)
- [ ] XTemporal: ワークフロー、そのアクティビティ、TemporalXWorkflowClient、名前付きActivityOptions(workflows.md)
- [ ] それを開始するユースケース(トランザクションコミット後、決定論的なIDで)
- [ ] 実行ファイル: Serve内のTemporalクライアント; ワーカーグループとそのRunルート
- [ ] テスト: タイムスキップサーバー上のワークフロー、モックを使ったアクティビティ
- [ ] swift build と swift test; 修正して繰り返し、両者が警告なしでパスするまで

CI/CDをセットアップする

- [ ] パッケージの種類: 公開ライブラリ、システムライブラリ、またはサービス(delivery.md#package-kinds)
- [ ] そのCIワークフロー(リリースのコミットでswift-microservices/ciを呼び出す); dependabot.yml; .license_header_templateと.licenseignore; シークレット
- [ ] ライブラリ: semverラベルと.github/release.yml; サービス: そのContainerfile
- [ ] CIのフラグでswift buildとswift test; 修正して繰り返し、両者がパスするまで

バックエンドをレビューする

- [ ] 境界チェックを実行する(packages.md#checking-the-boundaries)
- [ ] 各ユースケース: 5つのファイル、型付きthrows、ケースごとに1つのcatch、ヘルパーなし、正しいデータベースロール
- [ ] 各アダプターは変換と委譲のみ; すべてのエラーケースがマッピングされている
- [ ] 各ルート: 設定はそこでのみ読み取られる、ServiceGroup内のすべてのコンポーネントが依存関係順に
- [ ] Swift設定、FoundationEssentialsインポート、packageアクセス、命名(conventions.md)
- [ ] 所見を重要度順(致命的: テナント分離、認可、資格情報、ビルド; 主要: 形状; 軽微: 命名、レイアウト、ロギング)、それぞれにファイルと行または空のgrep、ルールと修正を記載; その後ユーザーの判断。コードは要求された場合のみ変更
- [ ] swift build と swift test; 各結果を報告、または実行できなかった理由を報告

リファレンス

該当する部分のリファレンスを参照してください:

リファレンスカバーする内容
system.mdサービスへの分割、コントラクト、サービス間の通信、共有パッケージ、計画
packages.mdターゲットとそのインポート、Package.swift、Swift設定、トレイトとFoundation、レイアウト、境界チェック
stack.mdライブラリ、各ターゲットがリンクするもの、Foundationリンク、バージョン選択
use-cases.mdモデル、エラー、リポジトリ、ポート、ユースケースの5ファイルと本文、トランザクション、認可
persistence.mdデータベースロールごとのスコープ、行レベルセキュリティ、ステートメント、マイグレーション、Valkey
grpc.mdコントラクト、protoサービス、ハンドラー、変換、ページング、ステータスコード、クライアント、トランスポート
gateway.mdOpenAPI型、リクエストコンテキストと階層、コントローラー、ウェブフック、エラー、アップストリームクライアント
workflows.mdワークフローの開始、ペイロード、決定論、アクティビティとオプション、バージョン、ワーカー
composition.mdコマンド、コンポジションルート、設定、ロギング、ServiceGroup
security.mdトラストモデル、mTLS、ユーザートークン、認可レイヤー、シークレット、ウェブフック
style.mdコードの読みやすさ: エラー、並行性、インポート、Foundation、型、フォーマット
testing.mdテストターゲット、各テストの証明内容、モック
delivery.mdパッケージ種類ごとのCIワークフロー、リリース、デプロイ、Containerfile、Dependabot
conventions.mdパッケージ、ターゲット、型、ファイル、キー、フォルダの命名

関連スキル

形状内のコードについては、これらがインストールされている場合にロードしてください。このスキルが形状を指定する場合、それに従ってください:

  • アクター、タスクグループ、キャンセレーション、Sendable診断、Swift 6移行: swift-concurrency
  • 引数ラベル、メソッド名、ドキュメンテーションコメント: swift-api-design-guidelines
  • ユースケース、ハンドラー、ワークフローのテスト: swift-testing-expert

関連スキル