Skip to main content

 

 

 

 
Language:
 
 
 
OutSystems

コアサービスを抽象化するための連携パターン

連携パターンが必要な理由

レコードの外部システムと連携してマスターデータを取得したりトランザクションを実行したりする必要がある場合、OutSystemsにインポートするコンセプトを抽象化するパターンに従って、以下を推進することをお勧めします。

  • システムの独立性: 外部システムを変更またはリプレースしても、影響を受けるのはコンセプトの抽象化の実装のみです。コンセプトのコンシューマには影響を与えません。

  • 拡張、正規化、最適化: 追加情報とビジネスルールを含むコンセプトを拡張し、表現とキャッシュ情報を正規化して、パフォーマンスを改善する機会。

コアサービスの抽象化 1- コアサービス
  • 元のサービスを拡張する
  • システムに依存しない(外部の変更に対する回復機能がある)
2- 連携サービス
  • 元のAPIを抽象化して内部のストラクチャとコンセプトに一致させる(別のシステムの補足情報で顧客コンセプトを構成するなど)
  • 連携タイプ(SOAP、REST、XIF、HTTPリクエスト、ファイルアップロードなど)を隠す
  • 技術的要件(アクセス資格情報、認可、エラー処理、統合監査など)に対処する

考え方としては、外部システムごとに1つの連携先を持つのではなく、独立したコンセプト(Customerなど)ごとに連携サービスを持ちます。

  • 1つのコンセプトが様々なシステムでサポートされる場合があり、連携サービスはその複雑さを抽象化します。

  • 1つのシステムが複数のコンセプト(CustomerやProductによるERPなど)をサポートする場合がありますが、各コンセプトには独自のライフサイクルがあります(CustomerのコンシューマはProductに興味がない場合があり、後者が変更されても影響を受けません)。

連携サービス - 外部システムの呼び出しをラップする

連携サービスは外部システムの呼び出しをラップすることで、連携の複雑さを隠し、再利用しやすいサービスを抽象化します。以下のキャンバスは、使用されている特定の連携プロトコル(REST、SOAP、DLLラッパーなど)にかかわらず、外部システムの呼び出しをラップする際に対処する必要がある主な問題を示しています。

連携ラッパーキャンバス:

連携ラッパーキャンバス

検証/セキュリティロジック - 入力の整合性を確認します。必要に応じて、セッションのユーザーにこの呼び出しを実行する資格があるかどうかを確認します。ユーザー例外をスローしてエラーを発生させます。

認証ロジック - 外部APIの呼び出しに必要な認証資格情報を準備します。

入力のマッピング - 正規化された入力を外部APIが必要とする形式にマッピングします。

外部APIの呼び出しと監査 - 外部APIを呼び出し、連携の証跡が必要な場合に呼び出しを監査します。

エラー処理の正規化 - 成功とエラーのメッセージ出力を処理し、そうした出力を返すのではなく例外をスローします。これはOutSystemsの想定どおりの動作です。

出力の正規化 - 返されたストラクチャを想定どおりの正規化された出力にマッピングします。

例外処理 - エラーは呼び出し元によってトラップされるため、通常は不要です。 連携の例外を監査したり、最終的にユーザーインターフェイスに表示される可能性のある例外メッセージを正規化したりするために使用できます。

データのニーズに応じた連携パターン

このセクションでは、様々なニーズ(ビジネスコンセプトや非機能面の要件)に応じたパターンをいくつか示します。重要なポイントは、どのようなタイプの連携が必要であっても、コアサービス(この例では、Customer_CS)のコンシューマは常に同じタイプの抽象化になり、レコードの外部システムを認識していないことです。

レコードの外部システムからデータを取得する際に、データの性質に応じてフィールドを以下の2種類に分類することで、連携のニーズを把握します。

  • 概要フィールド: エントリの表示または検索に使用されます。通常、これらのフィールドは、顧客名のように時間が経過しても変更されないか、または顧客所在地のようにごくまれに変更されます。

  • 詳細フィールド: 単独のエントリに関する詳細を表示するためにのみ必要です。これらのフィールドは、顧客残高のように、頻繁に変更され機密性が高いためレプリケートが難しいとみなされるものです。

連携パターンについて説明する前に、まず以下のデシジョンツリーを使用して、データのニーズに応じてパターンを選択します。アプリケーションの場合、選択したパスで収集されたパターンをすべて取り上げます。

連携パターンを選択するためのデシジョンツリー

太線の回答は、最も一般的な推奨パスを示しています。OutSystemsの組み合わせ、検索、スキャフォールディングに対してエンティティを提供することで、ほとんど必要のない複雑さを残すことなく、実装が加速します。

直接連携

このパターンは、サービスの抽象化に連携サービスを使用して、外部システムとの直接連携をわかりやすく表現しています。

直接連携 このシナリオでは、ERPから顧客データが取得されます。Customer_ISにはERPとのインターフェイスがあり、情報取得とトランザクション実行の両方の正規化されたAPIを抽象化します。 これにより、Integration Service APIが維持されている限り、コアサービスに影響を与えることなく外部システムを柔軟に変更できるようになります。

また、このシナリオには、データのローカルレプリカを保持するCustomer_CSのエンティティが含まれていません。レプリケートされたデータがERP以外で保持されない理由としては、ビジネス上の制約があること、あるいは(ほぼ)リアルタイムの要求がデータレプリケーションの遅延に対応していないこと(情報の変更頻度が高すぎること)が考えられます。

ただし、このパターンにはいくつかの制約があります。

  • データが取得されるたびにERPに余分な負荷がかかります。

  • ERPとの余分なオンライン通信によって遅延を感じることが増えます。

  • 顧客データを取得したり他の情報と組み合わせたりするために、OutSystemsのAggregateや高度なクエリの能力を最大限に活用できません。

  • 別のデータ取得が求められるたびに新しいAPIを提供する(何らかの基準でフィルタリングしたり、ある程度の詳細を含めたりするなど)ために、Customer_ISを絶えず拡張する必要があり、ERPチームとの強い依存関係も必要になります。通常、こうした依存関係を回避するために、開発者は既存のAPIを不適切に再利用する傾向があります。たとえば、4個のフィールドのみが必要な場合に50個のフィールドを返すメソッドを使用するということがあります。

メリット デメリット
データが常に最新の状態である APIが増える(取得のユースケースにつき1個)
遅延が増える
外部システムへのヒットが増える

概要データのコールドキャッシュ

外部システムとの連携のパフォーマンスを改善する必要性を感じた場合は、頻繁に変更されないデータをキャッシュすることから始めることをお勧めします。このようなデータは「コールドデータ」と呼ばれ、このキャッシュパターンにコールドキャッシュという名前を付けます。

コールドキャッシュはデータベース全体を同期するのに非常にコストがかかり、(リストではなく)個々のエントリにのみ詳細が必要な場合に使用されます。概要データはエントリを検索するために必須ですが、実際に詳細までアクセスされるのがエントリ全体の10%にすぎない場合は、エントリ全体を同期する必要はありません。

このパターンが実装されると、以下のようになります。

  • 頻繁に表示、結合、または検索される概要データのみがキャッシュされます(単独のエントリの全詳細は外部システムで直接取得できます)。

  • 完全同期を頻繁に行う必要はありません(概要情報は頻繁に変更されません)。

バッチ同期によるコールドキャッシュ

コールドキャッシュを実装する際の最も簡単な設計アプローチは、キャッシュデータモデルを作成し、バッチによる同期プロセスを設定してキャッシュデータを管理することです。

Customer_CSにローカルエンティティを追加すると、直接連携パターンの制約を克服し、成熟したコアサービスが実際に作成されます。

バッチ同期によるコールドキャッシュ 連携サービスは、簡素化され安定します。データ取得のニーズごとに無数のアクションを提供するのではなく、最後の同期以降に更新されたすべての顧客の関連データを取得するメソッドを提供します。

Customer_CSは、連携サービスを通じて情報を定期的に同期するタイマーを備えています。情報の複雑なマージを避けるために、この同期はERP(データのマスター)からコアサービスへの一方向にする必要があります。逆方向については、Customer_CSが更新された際に、更新が成功して最初にERPで同期的にコミットされることを確認してください(ライトスルーポリシー)。

メリット デメリット
APIが簡素化される データが古くなっている場合がある
OutSystemsでデータを組み合わせることができる
ソースシステムへの影響が少ない
コアサービスの顧客が同期の影響を受けない
同期ロジックを分離する

同期プロセスが複雑すぎて絶えず調整している場合は、コアサービスから同期プロセスを抽出し、さらに外部システムからCustomer_CSを分離することを推奨します。

同期ロジックを分離する 同期によっていくつかの連携を調整する必要がある場合、それも分離を行う理由になります。たとえば、顧客と顧客定義ファイルがそれぞれ別のシステムに保存されている場合、定義ファイルが顧客を参照しているため、同期では定義ファイルの前に確実に顧客を同期させる必要があります。

Customer_CSのコンシューマが同期コードによる影響を受ける必要はありません。また、将来的にERPが非推奨になり、OutSystemsで開発された機能にリプレースされる場合、同期コードを除去してもまったく影響はありません。

この例では、Customer_Sync連携サービスを通じて定期的に最新情報を取得してCustomer_CSに同期します。Customer_CSは、引き続きCustomer_ISを利用してオンライントランザクションを実行します。

リアルタイム同期

通常では、検索、表示、組み合わせに必要な概要データを含むコールドキャッシュは非常に安定しており、リアルタイム同期を必要としません。ただし、状況によっては、アプリケーションが確実に動作するように、リアルタイムで最新の状態にしておく必要のあるフィールドを概要情報に含める必要があります(たとえば、外部システムから車両の情報を取得する必要がある場合、頻繁に変更されるフィールドである各車両の現在位置を概要リストに含めることが重要です)。

リアルタイム同期 リアルタイム同期では、レコードの外部システムがOutSystemsをコールバックして、リアルタイムで変更(この例では、顧客の更新または挿入)を通知する必要があります。

APIモジュールとISモジュールはコアサービスを完全に分離して、コアサービスが外部システムと同期プロセスに依存しないようにします。

メリット デメリット
APIが簡素化される システム間の依存関係が増える
OutSystemsでデータを組み合わせることができる キューが提供されない場合、負荷の高い変更には適していない
ソースシステムへの影響が少ない
データが常に最新の状態である
リアルタイム同期のキュー設定

デフォルトのリアルタイム同期は比較的実装しやすいですが、大量の変更には適していません。この場合、解決策はキューを実装して同期を並列処理することです。

リアルタイム同期のキュー設定

リアルタイム同期の順序付け

外部システムが同時に複数の更新リクエストを(マルチスレッドなどで)発生させる準備ができている場合でも、それらのリクエストが正しい順序で確実に受信、処理されるとは限りません。この問題に対処する方法の1つを以下に示します。

リアルタイム同期の順序付け

詳細の遅延読み込み

上記のパターンは、概要データフィールドを処理する際の一般的な連携パターンに対応します。詳細フィールドはどうでしょうか。 詳細が外部システムから取得された後に頻繁に再利用される場合、詳細の取得をオンデマンドで実行するにはコストがかかりすぎるおそれがあるため、遅延読み込みパターンを設定することを推奨します。

詳細の遅延読み込みパターンを実装する方法

  • ローカルキャッシュからデータの取得を試みます。見つからないか古くなっている場合は、外部システムからエントリの詳細を取得してキャッシュします(リードスルーキャッシング)。

    • キャッシュされた詳細には、一定期間が経過した後にソースから強制的に更新するために、有効期限が設定されている場合があります。

    • あるいは、キャッシュデータを再利用する前に、レコードの外部システムからその情報の最終更新タイムスタンプを取得してローカルタイムスタンプと比較し、エントリが古くなっているかどうかを判断します。

  • 概要データもキャッシュされている場合は、別の詳細エンティティで詳細をキャッシュします。

  • 容量を節約するには、古くなった詳細データをタイマーで定期的に消去します。

異なるパターンを組み合わせるのが一般的です。つまり、定期的に概要データをキャッシュし、必要に応じて詳細の遅延読み込みを行います。

透過サービス

同じ種類の情報のソースが複数ある場合、通常は形式やAPIが異なっているため、同期プロセスはより複雑になります。

複数のソースによる透過サービス

Customer_Syncはレコードの全システムとの同期を調整して、Customer_CSの1つの顧客データレプリカを更新します。これにより、透過サービスが作成されます。

この例では、Customer_CSは顧客を更新できません。このパターンは、最も一般的な透過サービスです。このサービスでは、情報が様々なソースから入ってきますが、逆方向に流れることはありません。たとえば、様々なソース/形式の電気料金や電話料金の測定値などです。それらはローカルで訂正または修正される場合がありますが、ソースに送り返されることはありません。

ただし、変更内容を送り返すことが要件になっている場合は、特別なモジュールを追加する必要があります。Customer_ISは、トランザクションを適切なシステムに実際に送信するインターフェイス(ドライバ)を抽象化します。

透過サービス 1- 連携サービスは様々なシステムの存在を抽象化して、リクエストを適切なドライバにルーティングします。

2- 各システムはそれぞれ異なるドライバと連携します。すべてのドライバは同じシグネチャのAPIを提供します。

3- 各顧客はそれぞれ異なるシステムにいる可能性があります。