MuleSoft Composerで後悔した設計判断:簡易連携のつもりが泥沼化したインテグレーションの記録

後から「やらなければよかった」と思った設計

あるプロジェクトで、Salesforceと外部のSaaSツール間で簡単なデータ連携を行う必要がありました。要件は「Salesforceでリードが作成されたら、そのリード情報を外部SaaSツールに登録する」という、まさにMuleSoft Composerがターゲットとするようなシンプルさでした。当時の私は、開発速度とメンテナンスコストを考慮し、「この程度の連携ならComposerで十分だろう」と判断し、設計を進めました。ComposerのGUIでポチポチと設定を進められる手軽さに魅力を感じ、数日で連携フローを構築し、初期テストも順調に完了しました。あの時の自分に、もっと慎重になれと言いたい。

複雑なデータ変換ロジックへの対応

最初の段階では、Salesforceのリード項目と外部SaaSツールの項目が比較的きれいにマッピングできました。しかし、プロジェクトが進むにつれて、以下のような追加要件が次々と舞い込んできたのです。

  • カスタム項目への複雑なマッピング:外部SaaSツール側の特定の項目が、Salesforceの複数の項目を結合したり、特定の条件に基づいて異なる値をマッピングしたりする必要が生じました。例えば、「Salesforceのリードソースが'Webinar'で、かつ所属部署が'Sales'の場合のみ、外部SaaSツールの'キャンペーン区分'に'Priority Webinar'と設定する」といった具合です。
  • `If/Else If` ステップのネスト地獄:Composerでは条件分岐を`If/Else If`ステップで設定できますが、これが複雑化するとGUI上での視認性が著しく低下します。特に、複数の条件が絡み合うマッピングや、特定のデータクレンジング(例:電話番号から記号を除去、郵便番号のフォーマット統一)をGUIの関数で表現しようとすると、ステップが縦に伸びてしまい、どこで何をしているのか一目で理解するのが困難になりました。当時は、GUI上でポチポチ設定できることに喜びを感じていましたが、今思えば、コードで書く方がはるかにメンテナンス性が高かったでしょう。
  • Salesforce内外データの複合Lookup:外部SaaSツールに登録する際に、Salesforce内の別のオブジェクト(例:取引先)から情報を取得したり、さらには別の外部マスターデータ(これもComposerでHTTPコールアウトで取得)と照合して値を補完したりする必要が出てきました。複数の`Lookup`ステップや`Call an external API`ステップを挟むことで、フローはさらに長大になり、処理順序の把握も大変になりました。

結果として、当初はシンプルだったはずの連携フローが、GUI上でスクロールしないと全体像が見えないほど複雑化し、ちょっとした変更を加えるにも全体のロジックを読み解くのに時間がかかる状態になってしまいました。当時は「Composerでここまでできるのか!」と感心していましたが、それは同時に「Composerでここまで無理やりやるべきではなかった」という後悔に変わっていきました。

エラーハンドリングと再実行戦略の限界

インテグレーションエンジニアとして、エラーハンドリングは最も重要な側面の一つです。Composerも基本的なエラー処理は備えていますが、特定のビジネス要件を満たすには粒度が不足していました。

  • 標準エラー処理の物足りなさ:Composerのフローが失敗した場合、管理コンソールでエラーを確認できますが、「何が原因で」「どのデータで」「具体的にどう対処すべきか」という詳細な情報は得にくいことが多かったです。特に、外部API呼び出しで4xxや5xxエラーが返ってきた場合、そのエラーメッセージを解析してフロー内で適切な分岐処理を行うことが困難でした。
  • 部分的な失敗に対するリカバリ:例えば、Salesforceから100件のリード情報を外部SaaSツールに連携するフローで、そのうち5件だけ外部SaaSツール側でエラーになったとします。Composerのフローは全体が失敗扱いになり、成功した95件も含めて再実行するか、手動で5件だけを特定して対応する必要がありました。本来であれば、エラーになった5件だけを自動的にリトライするか、特定のカスタムオブジェクトに記録して後から一括で処理するような仕組みが必要でした。
  • 特定条件でのリトライが困難:外部SaaSツールのAPIが一時的にダウンしていた場合、数分後に自動的にリトライしてほしいという要件がありました。しかし、Composerの標準機能では、このような高度なリトライ戦略(exponential backoffなど)を組むことは非常に困難でした。結局、Salesforce側でカスタムオブジェクトとFlowを組み合わせて、失敗した連携要求を一定時間後に再キューイングするような仕組みを別途構築する羽目になりました。これはComposerのメリットである「ノーコード・ローコード」を大きく損なう結果となりました。

Composerは「ある程度の」自動化は得意ですが、「複雑な」自動リカバリや「高度な」エラーハンドリングを求めると途端に限界が見えてきます。当時は、Composerの制約内でいかに要件を満たすかを模索しましたが、最終的には別の手段に頼る部分が多くなり、設計の選択ミスを痛感しました。

パフォーマンスとスケーラビリティの課題

当初、数十件程度のリード連携だったのでパフォーマンスは問題ありませんでした。しかし、マーケティングキャンペーンが活発化し、一度に数百件、時には数千件のリードがSalesforceに登録されるようになると、Composerの処理時間や安定性に課題が見え始めました。

  • `Loop` ステップでの大量データ処理:Composerのフロー内でリストを処理する際に`Loop`ステップを使うことがありますが、これが大量のデータに対して実行されると、処理時間が伸びるだけでなく、場合によってはタイムアウトすることもありました。Composerは、基本的にレコード単位のトリガーが中心であり、大量のデータをバッチ処理的に効率よく扱うのには限界があります。特に、ループ内でさらに外部APIを呼び出すような処理は、直列処理になるためパフォーマンスに大きな影響が出ました。
  • API呼び出しの並列処理への非対応:ComposerのHTTPコールアウトは基本的に直列で実行されます。大量のレコードそれぞれに対して外部APIを呼び出す必要がある場合、これが大きなボトルネックとなります。MuleSoft Anypoint Platformであれば、非同期処理やバッチ処理、並列処理を柔軟に設計できますが、Composerにはそのような高度な制御オプションがありません。
  • 監視ダッシュボードからの詳細なボトルネック特定:Composerの管理コンソールからフローの実行状況や成功・失敗を確認できますが、特定のステップがどれくらいの時間を消費しているか、なぜ遅延しているのかといった詳細なパフォーマンス分析を行うのは困難でした。結果として、問題が発生した際には、手動でテストデータを流して挙動を観察するような、非効率なデバッグ作業を強いられました。

今振り返れば、あのプロジェクトはMuleSoft Composerの適用範囲を誤った典型例だったと思います。当初の簡易連携という要件は、プロジェクトのフェーズが進むにつれて急速に複雑化し、ComposerのGUIベースのローコード開発ツールとしての限界を露呈しました。

もし今、同じようなプロジェクトに直面したら、私はComposerを提案する前に、将来的な拡張性、データ量、エラーハンドリングの粒度、パフォーマンス要件について、より詳細なヒアリングとアセスメントを行うでしょう。そして、少しでも複雑化の兆候が見られるのであれば、迷わずMuleSoft Anypoint Platformや、SalesforceのApexを使ったより柔軟なインテグレーションアプローチ(例: Queueable Apex, Batch ApexとCalloutを組み合わせる)を検討するよう強く推奨します。Composerは非常に強力なツールですが、その「簡単さ」に惑わされてはいけないと、あの時の苦い経験から学びました。

これは当時の自分向けのメモだ。

コメント