ゲートウェイ(Gateway)パターン(PofEAA)
参考書籍一覧(Amazon アソシエイトリンク)
外部システムまたはリソースへのアクセスをカプセル化するオブジェクト。
エンタープライズアプリケーションアーキテクチャパターン 第18章 ベースパターン 18.1 ゲートウェイ
FacadeパターンやAdapterパターンに近いパターンではあるが、主な責務は外部リソースへのアクセスとそれをラップするインターフェースを構築することである。
マイクロサービスで他サービスへの通信手段として構築するのが、典型的な適用例だろう。
require 'open-uri'
require 'json'
class AnotherServiceGateway
SERVICE_URL = '...'.freeze
def find_user(id)
get("/users/#{id}")
end
def get(path)
JSON.parse(get_request(path))
end
def get_request(path)
open(SERVICE_URL + path)
end
end
上記はREST APIサービスのケースだが、メッセージベースのサービスでも同様に実装すれば良い。
サービススタブ(ServiceStub)パターンと組み合わせることで、テストを容易に実行できるようになる。どのように実際のクラスとサービススタブを入れ替えるかは色々なやり方があると思うが、RailsでRspecを用いているケースの参考例を示しておく。
# spec/rails_helper.rb
# 最終行に以下を追加
Dir[Rails.root.join('spec/spec_helpers/stubs/*.rb')]
# spec/spec_helpers/stubs/another_service_gateway.rb
# オープンクラスで上書き
class AnotherServiceGateway
def self.get_request_return=(value)
@get_request_return = value
end
def self.get_request_return
@get_request_return
end
# 差し替えの値が指定されていなければ元の挙動にする
# 元の挙動をするか切り替えるフラグを用意しても良い
alias_method :super_get_request, :get_request
def get_request(path)
value = self.class.get_request_return
return super_get_request(path) if value.nil?
value.to_json
end
end
# 適当なspecファイルの中
Rspec.describe '...' do
before { AnotherServiceGatewayStub.get_result_return = {id: 1, name: '山田太郎' } }
end