BASEプロダクトチームブログ

ネットショップ作成サービス「BASE ( https://thebase.in )」、ショッピングアプリ「BASE ( https://thebase.in/sp )」のプロダクトチームによるブログです。

ローカル開発環境のために外部サービスをモック化する

BASE の Service Dev にて主に決済周りのバックエンド開発をしている翠川(@midori44)です。 昨年は PayPal決済の導入 のプロジェクトでメインエンジニアとして携わらせていただきました。 今回は決済周りの開発をしていく中で、社内の開発環境を整えた話をします。

ローカル開発環境での課題

BASEでは現在、BASEかんたん決済 として6つの決済方法を提供しています。

日々の機能開発をしていく中で、すべての決済方法において各機能が正しく動作するかを確認するために、ステージング環境や社内検証用のQA環境だけでなく開発者のローカル環境でも決済をテストできるようになっています。

新機能のリリース時にはもちろん本番環境で実際の決済を通して動作確認するわけですが、開発中のテストの度に本番相当の決済をするわけにはいかないので、各決済代行会社様のほうで用意していただいている検証用サーバーやsandbox環境に接続してテストすることになります。

基本的にはそれで問題ないのですが、キャリア決済に関してだけはちょっと他の決済とはフローが異なることから、ローカルでのテスト決済ができない状態になっていました。

f:id:midori44:20201020142829p:plain
キャリア決済のフロー

キャリア決済では、購入者は一度カートを離れて決済代行サービスのほうで購入手続きを完了します。そのため、決済が確定したかどうかはwebhookで受け取る必要があるのですが、外部にある決済代行サービスは開発者のローカル環境にあるwebhookサーバーへアクセスできません。

もちろん、外部アクセスできるhttpサーバーを立ててリモートフォワードなどをすれば可能ですが、開発用の個人マシンでそこまでするのはリスクが高く現実的ではありません。

ということで、キャリア決済の動作確認をしたいときは共用の検証環境で確認するという方法で長らく運用されていましたが、やはり不便に感じる声が多かったのでDocker上で動く決済代行サービスのモックサーバーを作って解決しました。

外部サービスのモック化

弊社のローカル開発環境はDockerで構築されています。Docker Composeの設定ファイルはGitHubで管理しており、カートが動いているwebサーバー、ショッピングアプリ用のAPIサーバー、データベース用のDBサーバー……等々、各種サーバーをコマンド1つで立ち上げることができます。

今回は、その中の1つのコンテナとしてキャリア決済用のモックサーバーを立ち上げられるように準備します。

適当なwebサーバーを用意して、実際の決済代行サービスと同じレスポンスを返すモックサーバーを作ります。今回は購入中のリダイレクト先としてブラウザからアクセスするため、正常系だけでなく異常系もテストできるように、画面上の操作によって意図的にエラーを起こせるようにしておきました。

f:id:midori44:20201020142503p:plain
モックサーバーのサンプル画面

純粋なAPIサーバーの場合は、異常系のテストをしたいときは『特定のリクエストを渡された場合にはエラーを返す』という実装が一般的かと思います。 たとえば PayPal のsandbox環境では、リクエストヘッダーに PayPal-Mock-Response を渡すことで任意のエラーを受け取ることができるようになっています。 https://developer.paypal.com/docs/api-basics/sandbox/request-headers/

Docker Composeに定義を追加して、用意したモックサーバーをコンテナとして立ち上げられるようにします。今回のモックサーバー構築で注意したいのは、購入者に確認画面を表示させるためのブラウザ経由でアクセスと、裏でwebhookサーバーへ通知を飛ばすためのコンテナ間通信の2つの通信が発生することです。

弊社のDocker環境では本番と同じように任意のホスト名かつSSLでアクセスできるようDNSやリバースプロキシを通しているため、docker-compose.ymlextra_hosts を設定してモックサーバーからwebhookサーバーへのコンテナ間通信のときにもリバースプロキシを通すようにする必要がありました。

最後に

外部サービスのサーバーを丸ごとモック化することで、一通りの動作確認をDockerネットワーク内で完結させることができました。

今回はローカルでの動作確認が最後までできないことからのモック化でしたが、外部サービスに対する動作確認(こちらからのリクエストに対して想定したレスポンスが返るかどうか)と、自サービス内の動作確認(正常レスポンスもしくはエラーを受け取ったとき正しく処理されるか)を分けて考えるためにも、適切なモック化は役に立つかと思います。

BASEでは開発環境の整備や中長期的な技術基盤の改善を担っていくエンジニア、および120万ショップの決済を支えていくエンジニアを募集しています。

binc.jp