Skip to main content

 

 

 

 

Template:OutSystems/Documentation_KB/Breadcrumb_New_Layout

 

Template:OutSystems/OSLanguageSwitcher
Language:

 

 

 

 

 
OutSystems

アーキテクチャ設計図からの開発

この記事では、最終的なアーキテクチャ設計図を実行に移す方法について主に説明します。

前の記事では、架空の顧客のユースケースについて説明しました。Soccer Fields Fictitiousが、利用者がサッカー競技場をオンラインで予約できるWebアプリケーションを作成する場合を考えます。

説明されている手順を適切に実行するため、続行する前にOutSystems ForgeからSoccer Fields Appリソース、Soccer Field Sample APIField Core Servicesアプリをダウンロードして、Personal Environmentにインストールしておいてください。

要件

アプリケーションの要件は以下のとおりです。

  • サッカー競技場と各競技場の特徴(規模、空き状況、1時間あたりの料金など)のリストを表示する機能

  • 利用者がサッカー競技場を選択して予約する機能

サッカー競技場のリストは外部システムによって提供されます。つまり、実際の競技場の管理や決済の処理はこのアプリケーションのスコープに含まれません。

アーキテクチャ設計

前の記事で、最終的なアーキテクチャ設計図が完成しました。以下の図はその設計図であり、これが開発フェーズの開始点になります。

アーキテクチャ設計図

以下のセクションでは、設計図を実際のOutSystemsアプリケーションに変換する処理について説明します。

設計図の理解

これが第一歩になります。内容を理解するには、以下が必要です。

  • モジュールとなる要素やアプリケーションとなる要素を特定できる必要があります。

  • 各要素の性質と目的を理解し、コードを適切な場所に配置できるようにする必要があります。

以下の表は、表記規則を示しています。

表記規則
角が丸い長方形はモジュールを表します。長方形の色によって、各モジュールをArchitecture Canvasのレベルにマッピングすることができます。
内側にモジュールを含む長方形はアプリケーションを表します。この長方形はモジュールより薄い色です。この色によって、アプリケーションをアーキテクチャレイヤーにマッピングすることができます。

アーキテクチャ設計では、各要素の性質を文書化する必要があります。この詳細の追加はアーキテクトが行います。

続行するには、ビジネス要件を検討し、各モジュールの目的とスコープを理解しようとする必要があります。

この例では、2つのLifeTimeアプリケーションがあります。

  • Soccer Fields App: ユーザーインタラクションと競技場の予約を行うためのコードが含まれるメインアプリケーションです。

  • Field Core Services: 外部ソースに接続して競技場の情報を取得するためのサポートアプリケーションです。

モジュールの依存関係の特定

アーキテクチャを強固にし、理解しやすくするためには、モジュール間の関係や階層を特定することが効果的です。モジュール間の依存関係を把握することは、Discoveryツールによって検証されるArchitecture Canvasの検証ルールに対する違反を避けるための最初の手順として適しています。

これはコアレベルで最も重要です。コンセプトが適切に分離されていないと不適切な依存関係によって、循環参照が発生します。コードのリファクタリングが必要になり、リスクやコストが増加する傾向があります。

インサイトを以下に示します。

  1. Booking_BLは、競技場と利用者の2つのコアコンセプトの構成によって機能します。これら2つのコアコンセプトは独立しています。つまり、利用者が競技場を予約すると、Booking_BLモジュールはその関連付けを保持します。

  2. Field_CSは、パフォーマンス上の理由で既存の競技場のローカルレプリカを含みます。Field_Syncモジュールはこのローカルレプリカを同期し、情報をField_ISから読み取ってField_CSに書き込みます。

  3. 外部システムへの書き込み操作ではField_CSField_ISとの接続を使用します。ユーザーが競技場を予約すると、それが外部システムに通知されます。

  4. Field_ISは、外部のREST APIに接続して取得した情報を内部形式に正規化する唯一のモジュールです。このレベルの抽象化は、外部システムに依存せずにシステムを拡張するために極めて重要です。

アーキテクチャ設計図にこの情報が含まれている必要があります。含まれていない場合は、この演習を行ってアーキテクトとともに結果を検証することを推奨します。

モジュールとアプリケーションの作成

このセクションでは、モジュールとアプリケーションの開発について説明します。まずは、Service Studioを開いて実際にやってみます。

エンドユーザーアプリケーション

アーキテクチャ設計に従い、最初のアプリケーションとモジュールを作成します。

  1. Service Centerで、[New Application]を選択して[Web App]を選択し、[Liverpool]テーマを選択します。アプリケーションに「Soccer Fields」という名前を付け、[CREATE APP]をクリックします。

  2. これで最初のアプリケーションが作成されました。次に最初のモジュールを作成します。

    エンドユーザーアプリケーションで最初に作成するモジュールは、テーマモジュールです。テーマモジュールを使用すると、ベストプラクティスに従い、アプリケーションのスタイルを分離してカスタマイズできます。

    • デフォルトでは、スペースを含まないアプリケーション名を使用してモジュールを作成することが推奨されます。そのため、「SF_Th」という名前に変更し、[Responsive]モジュールタイプを選択して、[CREATE MODULE]ボタンをクリックします。

    モジュールの作成

  3. アプリケーションをパブリッシュする間に、Emails UIフロートMainFlow UIフローを削除する場合があります。その後、[1-Click Publish]ボタンをクリックしてアプリケーションをパブリッシュできます。

    1. 「Emails」UIフロート「MainFlow」UIフローを削除します。

    Emails UIフローとMainFlow UIフローの削除

  4. このアプリケーションのフロントエンドモジュールであるSoccer Fieldsを作成します。新しいレスポンシブモジュールを作成してパブリッシュします。

    フロントエンドモジュールの作成

  5. SoccerFieldsモジュールをホームモジュールに設定します。

    SoccerFieldsモジュールのホームモジュールの設定

  6. アプリケーションの構成をよく見ると、Booking_BLPlayer_CSの2つの新しいモジュールが含まれていることがわかります。以下の図のように、これらの2つの新しいモジュールを作成して[Blank]モジュールタイプを忘れずに選択します。

    • Booking_BL:

      Booking_BLモジュールの作成

    • Player_CS:

      Player_CSモジュールの作成

コアアプリケーション

  1. 「Soccer Fields」アプリケーションのときに実行した最初の手順を繰り返します。ただし、ここではアプリケーションに「Field Core Services」という名前を付けます。

  2. 「Field Core Services」アプリケーションの最初のモジュールを作成します。以下の図のように、最初のコアモジュール(Field_IS)のモジュールタイプは[Responsive]ではなく[Blank]です。これは、「Field Core Services」がコアサービスアプリケーションであり、ベストプラクティスに従ってエンドユーザー画面をホスティングしないようにする必要があるためです。

    Field_ISモジュールの作成

  3. CREATE MODULE]をクリックした後、[1-Click Publish]ボタンをクリックしてアプリケーションをパブリッシュします。

  4. これでコアアプリケーションと最初のモジュールが作成されました。次に残りのField_CSモジュールとField_Syncモジュールを作成します。モジュールごとに[New Module]ボタンをクリックし、それぞれのモジュール名に変更して、[Blank]タイプを選択します。[CREATE MODULE]ボタンをクリックし、モジュールをパブリッシュします。

基盤アプリケーション

ここでは例を簡単にし、再利用できるようにするため、基盤アプリケーションを作成する必要はありません。

実装

これでアプリケーションとモジュールが作成されました。次にプログラミングを開始します。

アプリケーションが利用する競技場APIをシミュレーションするため、この例はOutSystemsによって事前作成された、必要な情報のみを公開するシンプルな模擬APIモジュールに基づいています。RESTを使用して通信するため、他のテクノロジーも適用できます。

この記事は、OutSystemsのアーキテクチャとその実践方法について説明するものです。OutSystemsを使用してAPIを実装する最適な方法については説明していません。

このAPIは非常にシンプルであり、含まれるリソースは競技場のみです。すべてのリクエストは、有効なキーを含むAPI_KEYリクエストヘッダーを送信する必要があります。これはサンプルであり、有効なAPI_KEYは「outsystems_is_awesome」です。

アーキテクチャパターン

前述のとおり、アーキテクチャ設計ではアーキテクトがアーキテクチャパターンを文書化する必要があります。

このユースケースでは、サッカー競技場の情報を取得するための重要な連携パターンがあります。

サッカー競技場の情報の取得

このパートナーでは、3つのアーキテクチャパターンに重点を置きます。

  1. 外部システムとの連携

  2. データのローカルレプリカ

  3. データの同期

パターンからコードへの変換

  1. 外部データベースとの連携

    外部APIとの連携から実装を開始します。これを行うには、Field_ISモジュールが最適です。その理由は、このモジュールが外部APIからのデータの利用と正規化を行う技術的なラッパーであるためです。このモジュールは、外部APIのすべての特殊性の抽象化と分離を行います。

    1. 外部APIを利用する

      Field_ISモジュールを開き、[Logic]タブをクリックし、IntegrationsフォルダにあるRESTノードを右クリックして、[Consume REST API…]を選択します。ここで、外部APIの開発チームからSwagger仕様が提供されているとします。この場合は、すでに説明したサンプル模擬サービスを使用します。そのためには、[ADD ALL METHODS]をクリックし、SwaggerファイルのURL(https://expertsp10-dev.outsystemsenterprise.com/SFF_Sample_API/rest/v1)を入力します。 [OK]をクリックすると、外部APIは以下のようになります。

      外部APIの利用

    2. APIキーを送信する

      外部APIとの連携を完了するには、API_KEYリクエストヘッダーで有効なキーを送信する必要があります。これを実現するには、OnBeforeRequestイベントを実装します。そのためには、エンドポイントを選択します。以下の図のように、On Before Requestプロパティの横のドロップダウンをクリックして[New OnBeforeRequest]を選択します。

      APIキーの送信

      OnBeforeRequestイベントの実装は以下のようになります。

      OnBeforeRequestイベントの実装

    3. 競技場のリストと概要データを取得する

      まず、Field_IS_Summaryという名前のストラクチャを作成します。このストラクチャは、外部APIから取得した競技場のリストを上位レイヤーに提供するアクションの出力になります。

      これらの外部データ型からコンシューマを抽出し、それによって将来の外部データ型の変更による影響を避けるため、ここではField_CSは外部APIによって自動生成されるストラクチャを再利用しません。

      ストラクチャのアトリビュートは以下のようになります。

      Field_IS_Summaryストラクチャ

      これでコアサービスが利用するサーバーアクションを作成できるようになりました。[Add Server Action]をクリックし、「Field_IS_GetSummaryFields」という名前を付けます。Publicプロパティを「Yes」に設定し、以下のロジックを実装します。

      Field_IS_GetSummaryFieldsアクションの作成

  2. データのローカルレプリカ

    パフォーマンスを向上させ、エンドユーザーにより優れたユーザーエクスペリエンスを提供するため、アプリケーション側でデータのローカルレプリカを作成します。これを実現するには、外部システムから取得したデータを保存するローカルエンティティを作成します。

    1. ローカルエンティティを読み取り専用で公開する

      Field CSで、新しいFieldエンティティを作成します。Field ISの概要ストラクチャによって返されるすべてのフィールドを追加します。競技場レコードの特定に必要なフィールド(NameやDimensionなど)を忘れずに必須に設定します。

      PublicプロパティとExpose Read-onlyプロパティを「yes」に設定します。他の外部モジュールがデータを直接変更できないようにする必要があります。エンティティは以下の画面のようになります。

      Fieldエンティティ

    2. CRUD(作成、取得、更新、削除)アクションを作成する

      エンティティを読み取り専用で公開するため、これらのエンティティのデータの作成を一元的に行うアクションを設定する必要があります。このアプローチは、一般的な操作(ロギングなど)をこのアクションに一元化できるというメリットもあります。これによってコードの重複を避けることができます。

      このシナリオでは、様々なタイプの競技場のレコードを作成するときに通常使用される2つの主要操作を行うアクションを作成します。サーバーアクションに新しいフォルダを作成し、Field_Createアクションを追加します。Fieldを入力パラメータとして追加し、Fieldの識別子であるidを出力パラメータとして追加します。アクションの本文にCreateOrUpdateField内部アクションをドラッグし、作成されたidを返す割り当てを最後に1つ追加します。

      CRUDの作成

      同じ手順を繰り返して、Field_CreateOrUpdateアクションを作成します。

  3. データのローカルレプリカ

Field_Syncモジュールでは、外部システムからローカルキャッシュへの非同期の同期ロジックを作成します。このモジュールはタイマーとロジックを含み、Field_ISField_CSを参照します。

特定の時間に同期タイマーがトリガーされます。そして、同期アルゴリズムによって、手順1で作成したField_IS_GetSummaryFields"**を使用してデータフィールドのサブセットを外部システムから取得します。以下に示す画面と手順は、競技場データの同期アルゴリズムの例を示します。

競技場データの同期アルゴリズム

  1. ロジックのタイムアウト(10分)を設定し、前のタイマーの進捗状況がある場合は取得して処理を続行します。このシナリオでは、タイマー設計時のベストプラクティス(タイムアウトしない、作業を繰り返さない、完全性を確保する、データ整合性を確保する)に従います。

  2. このIfロジックによって、ローカルキャッシュへの同期が必要なデータが残っているときの同期フローの開始と再帰が保証されます。

  3. ISモジュールでのアクションの実際の呼び出しは、ここで行われます。外部システムの呼び出しをトリガーし、同期するレコードの数を返します。

  4. このループですべての結果について繰り返し、Fieldエンティティで挿入/更新を行います。

  5. この条件の最初で、手順1で定義したロジックのタイムアウト(ベストプラクティス)に達したかどうかと、処理が必要なレコードが残っているかどうかを確認します。

    1. 10分のタイムアウトに達しておらず、処理が必要なレコードがまだ残っている場合は、アルゴリズムをもう一度繰り返します。

    2. ロジックの10分のタイムアウトに達した場合は、それまでの進捗を保存し、現在の実行が終了する前にタイマーを再起動します(タイマーのベストプラクティスが確保されます)。