OutSystems Developer Cloudのアーキテクチャ設計

そろそろ、OutSystems Developer Cloud (ODC)本格利用の日も迫ってきたので、2023/08/13時点の情報から、ODCにおけるアーキテクチャ設計についてメモしておく。

ODCについては、いまだに恒常的に触れる環境が無いので、以前テスト的に触った時の記録、ドキュメント・動画からのメモで構成している。

# 情報ソース
## 公式ドキュメント
[App architecture](https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/app_architecture/)とその下のドキュメント
## 動画
[Architecture Fundamentals in ODC](https://learn.outsystems.com/training/journeys/architecture-fundamentals-559)：ODCにおけるアーキテクチャの基礎と設計手順
[Architecture Patterns in ODC](https://learn.outsystems.com/training/journeys/architecture-patterns-581)：アーキテクチャ設計パターン（アーキテクチャ設計でよく発生する設計例）

## OutSystems 11におけるアーキテクチャ設計
以前Qiitaに書いた[Architecture Canvasを使った設計の骨格](https://qiita.com/jyunji_watanabe/items/147980fd974774e2fc39)を参照。

OutSystems 11の頃から、DDD（Domain Drive Design) の概念が使われていた。
- ドメイン⇒LifeTimeのTeam
- サブドメイン⇒Application
- サブドメイン内の概念⇒Module

という対応関係だった。
[OutSystemsのDDD情報まとめ](https://qiita.com/jyunji_watanabe/items/357470b3b632c232ce76)を以前作成した。

# 前提知識（OutSystems 11から変化のあった部分）
## アプリケーションがなくなる
OutSystems 11までは、各モジュールの入れ物としてアプリケーションがあり、リリースの単位だった。
アプリケーションは無くなり、これまでモジュールと呼んでいたものに相当するレベルの要素をAppと呼ぶ。

## モジュール種別に相当するものがシンプルになる
App (Web/Mobile)
Library
の2種類のみ。

## リリースはコンテナを移動させることで行う
Publishすると、Appの単位でコンテナ化されて保存される。
各環境（Stage）へのリリースはこのコンテナを移動させることで行う。

つまり、プログラムを格納するリポジトリは1個。
OutSystems 11では各環境ごとにリポジトリがあり、リリース時にソースを移動・整合チェック・コンパイルを行う、という動作だった。

## 参照関係の変化
AppがPublicにできる要素は弱い参照関係のもののみ。
LibraryがPublicにできる要素は強い参照関係のもののみ。

Appをそれぞれマイクロサービスとして設計することになる。

App・LibraryそれぞれでPublicにできる要素については、[Reuse elements across apps](https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/app_architecture/reuse_elements_across_apps/)の表を参照。

# Architecture Canvasがない
OutSystems 11での設計方法として、Architecture Canvasがあったが、ODC関係では見かけない。

恐らく、マイクロサービス志向を推し進めた結果、レイヤー数が3つもいらなくなったのか、それともこれから設計図法が出てくるのかはわからないが。

AppはEnd UserレイヤーとCore Businessレイヤーを兼ねる位置づけになり、LibraryがFoundationレイヤーに対応する。

# マイクロサービスがほぼ強制される
App間の参照が弱い参照（ActionやEntityの参照はHTTPS通信になる）であり、Library内にはEntityが作れない。

これだと、OutSystems 11でやっていたように、それぞれに役割を持つ複数のモジュールに分割し、組み上げることで一塊のアプリにする、というやり方が取りにくい。

一応、1Appを巨大なモノリスにしてしまう手はあるが、後で保守が大変だし、1開発チームが大きくなるとPublish時のコンフリクトが大変なのは変わらないはず。

実プロジェクトで試してみないとわからない部分もあるが、現実的にはマイクロサービス設計を強制されると思っていいのではないか。
そうしてみると、気になるのは、各開発者がマイクロサービス設計になじんでくれるか……。
（Reactive Web Appも導入時は同じ心配があったが、現在は各開発者はうまく対応しているように見えるので、大丈夫か？）

# 設計手順
## 1. 業務上の概念（business concept）を列挙する
タイトル通り。
業務要求から業務上の概念を抽出する。
OutSystems 11でいうDiscloseのステップに相当する。

## 2. 業務上の概念を束ねてBounded Contextを識別する
Bounded ContextはDDDの用語だが、ドキュメント上で明確な定義を与えられずに話が進んでいる。DDDなら（たぶん）ドメイン内でサブドメインをまとめたシステム上の区切りだが……。

ステップ1で抽出した概念を
- 業務担当者
- 業務やデータのフロー

の切れ目でまとめ上げ、まとめ上げたBounded Context間の依存関係を最小になるように努める。
OutSystems 11の設計手順ではOrganizeに対応していそう。
外部連携があるならここで識別しておく。

## 3. 所有権を検討
Bounded Context毎に以下の要素を識別する。
リリースサイクルの独立性を高めるため、Bounded Context毎にそれぞれ1つにするのが原則。
- Business Owner: 業務担当者
- Business Sponshor: 開発費用を負担する人
- Product Team: 開発チーム

これはOutSystems 11でも設計の過程で気にしていたこと。
[適切なアプリケーションの構成のための4つのルール](https://success.outsystems.com/ja-jp/documentation/best_practices/architecture/designing_the_architecture_of_your_outsystems_applications/application_composition/the_4_rules_for_correct_application_composition/)

## 4. 組み立て
- App間の依存を緩くする
- App内の凝集性を高める
- App内に複数の所有権が混ざらないようにする

を注意しつつ、AppとLibraryを組み立てる。
サンプルを見ると、App:Bounded Context=1:Nの関係になるようだ。