意地でも関心を分離する

マイクロサービスアーキテクチャにおいて、ある構造化されたデータを、構造を維持したまま別のコンポーネントでも使いたくなる誘惑が存在する。 例えば、ドメインロジックを扱うコンポーネントに「ユーザーの種別(ゲスト、メンバー、管理者)」という概念があり、API トークンの認可情報に含めたいとして、APIトークンを管理するコンポーネントはその概念に関与すべきだろうか。

// 関与しない定義
IssueToken(userType: string, expiresAt: Date): Token

// 関与する定義
enum UserType {
    Guest,
    Member,
    Admin,
}

IssueToken(userType: UserType, expiresAt: Date): Token

ここで安易にそうしてしまうと、「ユーザーの種別」の定義が変わったとき——例えば新たに「モデレーター」という種別が追加された場合、双方のコンポーネント両方のデプロイが必要となってしまう。互換性を維持する手間や、対応漏れに起因するバグのリスクが生まれるため、マイクロサービスアーキテクチャの利点が損なわれる。

そのため、マイクロサービスアーキテクチャを採用する際は、上流のコンポーネントに依存した表現・挙動を可能な限り排除すべきだ。 Protobufなどのモジュールシステムを使えば同一のスキーマを複数のコンポーネントで使いまわすことができるが、やり過ぎればコンポーネント間のロジックの漏洩や共依存の温床となってしまう。データを他のコンポーネントに渡す時は、例えそれが構造化されたものであっても、任意の文字列とみなして扱うべき、くらいの勢いで考えていきたい。