バックグラウンド
LoopBackは、 API開発者向けに構築された、オープンソースのNode.jsのフレームワークです。主な目的は、既存のサービス/データベースからマイクロサービスとしてAPIを作成し、Web、モバイル、IoTなどのクライアントアプリケーションのエンドポイントとして公開することです。 LoopBackは、APIリクエストの受け入れと、バックエンドリソースとのやり取りの間をつなぎます。 Loopbackと他のフレームワークの違いは、開発者がすぐに使用できる統合機能を使用してAPIロジックを実装できる点です。これにより、LoopBackはExpress、Hapi、 Sailsなどとは異なる、優れたAPI構成レイヤーとなっています。
LoopBackは、バージョン3.xまで、Express frameworkに構築されました。 結果的には、LoopBackをExpressに基づかせることは正しい決定でした。 Expressの力を借りることで、LoopBackは、「車輪の再発明」のごとく既存システムの修正に手間取られることなく、API作成エクスペリエンスの価値を高めることに集中できました。LoopBackは、npmのすぐに使用できるミドルウェアモジュールなど、Expressのエコシステムやコミュニティによる知識とサポートの恩恵が受けられるのも魅力です。
LoopBackを使用することで、開発者はまるでレシピに従うように簡単にAPIを作成-公開できます。LoopBackは、API実装の重要な側面をまとめた一連のコアコンセプトを導入します。そして開発者は、既存のデータベースやサービスからAPIを作成するために、LoopBackアプリケーションを足場とし、必要なJSON宣言とNode.jsコードを追加して、APIを数分で起動して実行できます。
LoopBackは、認証、承認、ルーティングなどのAPIユースケースの要求/応答パイプラインへの接続として、Expressのルーティングとミドルウェアを使用します。そして、受信HTTP処理機能を超えて、モデル、データソース、コネクタなどの統合機能を提供し、APIロジックがデータベース、REST API、SOAP Webサービス、gRPCマイクロサービスなどの様々なバックエンドシステムと対話できるようにします。また、インバウンド通信とアウトバウンド統合を結び付ける機能により、LoopBackはAPI開発者にとって非常に強力なフレームワークになります。 下の図は、LoopBackが典型的なエンドツーエンドAPI処理フローにどのように適合するかを示しています。
LoopBackは長年の開発歴とリリースにより、機能-ユーザー数ともに大幅に成長しました。 LoopBackは、開発者コミュニティにも広く受け入れられています。コミュニティによる 様々な拡張機能がその一例です。 コアチームもまた、コミュニティによるフィードバックから多くのことを学びながら、相互的にLoopbackを発展させています。
なぜLoopBack 4が生まれたのか
世の中の多くのプロジェクトと同様、LoopBackにもまた次のような課題が明らかになってきています。
-
より多くのモジュールとより多くの機能を備えたコードベースは、時間とともにより複雑になります。私たちはより多くのメンテナーとコントリビューターを助けたい一方、学習曲線は急勾配になっています。原因の1つは、JavaScriptそのものです。これは、型指定が弱く、コード間のコントラクトを明示的に定義するインターフェイス等の構造がありません。初心者には、かなりの背景知識が必要となります。
-
技術的な負債も累積しています。例えば、モジュール間で一貫性のないデザインや、異なる動作の機能フラグがあります。以下に例を示します。
- 各モジュールが、それぞれ異なるレジストリを使用して個々のアーティファクトを管理している。アーティファクトの例は、リモーティングメタデータ、モデル、データソース、ミドルウェア等。
- それぞれ異なるフレーバーを使用して、各レイヤーでカスタムロジックが要求/応答をインターセプトしている。レイヤーの例は、ミドルウェア、リモートフック、CRUD操作フック、コネクターフック等。
- ユーザーが新しい動作にオプトインできるようにする一方で、下位互換性を維持するために、機能フラグの追加が増えている。
- 一部の領域が現在の設計の限界に達し始めているため、新しい機能を追加したり、バグを修正したりすることがより困難になっています。
- このloopback-datasource-jugglerモジュールは、タイピング、データモデリング、検証、集約、永続性、サービス統合など、まるであらゆることを全て請け負っているキッチンシンクのようなものです。
- モデルには、データ表現、永続性、RESTへのマッピングなど、複数の役割があります。モデルはデータソースに関連付けられており、異なるデータソースに対して同じモデル定義を再利用するのは簡単ではありません。
- コアチームへのLoopBackモジュールのコード変更リクエストなしにフレームワークを拡張するのは、簡単ではありません。LoopBackの現在のバージョンには、様々なレイヤーでアドホックな拡張性があります。そのため、拡張ポイントは一貫して定義されていません。例えば、
- Expressを使用してミドルウェアを登録します。
- リモートフックを傍受するには、リモートフックを使用します。
- CRUDフックを使用して、CRUD操作に関するロジックを追加します。
- より多くのプロジェクトが、基になるプラットフォームとしてLoopBackを使用し始めています。このような使用例では、LoopBackを活用してメタデータ駆動型アプローチを使用してアーティファクトを管理および構成するために、LoopBack内部の詳細な知識と柔軟性と動的性が必要です。良い例を次に示します。
- テナント間のアーティファクトの分離を必要とする、マルチテナント
- モデル定義とデータソースを管理/アクティブ化する、メタデータAPI
- イベントやメッセージングなど、コネクタの新しい相互作用パターン
- モデル定義の追加のメタデータ
3.xのリリース以来、チームはLoopBackを維持し、前進させる方法についてブレーンストーミングを行ってきました。多くの課題解決を行い、既存のGitHubの問題をトリアージし、コミュニティメンバーとダウンストリーム製品に向き合い、関連するフレームワークとテクノロジーを評価して、次の質問に答えてきました。
- LoopBackの対象読者は誰か。LoopBackに興味があるのはなぜか。彼らは何のためにLoopBackを使用し、どのようにそれを使用するのか。
- 重大な問題点は何か。新しい基盤を再構築せずに、段階的に対処できるか。
- 最もリクエストの多い機能は何か。現在のデザインに、そういった機能を追加することは可能か。
- 世界中で最新かつ最高の技術は何か。それらを採用し始めたら、それらはどのような価値をもたらすのか。
- LoopBackの開発と保守をどのようにスケーリングするか。LoopBackを使用してAPIを作成する上で、大規模な開発チームが協力できるようにするにはどうすればよいか。
- コミュニティをさらに成長させ、そのエコシステムを拡大するにはどうしたらよいか。LoopBackにより多くのユーザーと貢献者をもたらすために何ができるか。
LoopBackは、Node.jsアプリケーション開発者以外も、以下のように様々なユーザーの間で注目を集めています。
- API開発者 -LoopBackを使用して、Node.jsでAPIを作成できます。
- LoopBackのメンテナーとコントリビューター -LoopBackプロジェクトによるモジュールのビルドとメンテナンスができます。
- 拡張機能の開発者 -LoopBackに拡張機能を提供して、フレームワークを強化できます。
- プラットフォーム開発者 -付加価値製品を構築するベースとして、LoopBackを活用できます。
そこでコアチームは、上記のすべてのグループのニーズを満たすために、大胆にLoopBackを再構築することを決定しました。この決定により、新世代のAPI作成プラットフォームであるLoopBack 4が始まりました。詳細については、ブログ投稿、Loopbackを簡単に拡張できるようにするための次のステップ、Loopbackを発表をお読みください。
目的
LoopBack 4の目標は次のとおりです。
- 最新かつ最高のテクノロジーの進歩に追いつく。
- メンテナンスの容易さと生産性のために、 ES2016/2017 と TypeScript を採用します。
- OpenAPI Specや GraphQL などの、新しい標準を採用します。
-
エコシステムを成長させるための拡張性を促進します。 -最小限のコアを構築し、拡張機能を介して他のすべてを実装できるようにします。 -より多くの 拡張ポイントと、拡張機能のドアを開きます。
- マイクロサービス向けのクラウドネイティブエクスペリエンスと連携します。
- Cloud Native Computing Foundationなどのイニシアチブを採用して、クラウドネイティブマイクロサービスを採用し ます。
- LoopBackをマイクロサービスエコシステムの第一級市民にします。
- モジュール間の複雑さと矛盾を取り除きます。
- 一貫したレジストリとAPIを使用して、アーティファクトとその依存関係を管理します。
- 複雑なモジュールをリファクタリングすることにより、技術的な負債を払い戻します。
- 構成可能性を高めるための個別の懸念。
- コントローラーやリポジトリーなどの新しい概念を導入して、様々な役割を担わせます。
- ランタイムを一連のサービスとして分類し、拡張ポイント/拡張パターンを使用して、登録、解決、および構成を管理します。
設計原則
LoopBack 4を構築するために「ビッグバン」アプローチを採用しないことにしました。代わりに、より小さなステップで段階的に複数の段階で構築を行っています。このアプローチにより、最初からLoopbackコミュニティとの関わりを高めることができます。アーキテクチャのシンプルさと拡張性を追求するために、以下の原則に従っています。
- 最初に命令型を、後に宣言型を
すべては APIs
を介してコードで実行できます。LoopBackチームまたはコミュニティの貢献者は、そのようなAPIを使用して様々なユーザーエクスペリエンスを作成できます。たとえば、モデルを定義するAPIを使用すると、アプリケーションでJSONまたはYAMLファイルでモデルを宣言して、モデルを検出およびロードできるようになります。拡張機能は、JSONスキーマ、デコレーターを含むES6クラス、OpenAPI仕様のスキーマ、さらにはXMLスキーマなど、他の形式のモデル定義をLoopBackモデル定義に解析できます。
また、デコレータなどのプログラミング構造を活用して 、開発者がコードでメタデータを提供できるようにすることも可能です。さらに、LoopBackアーティファクトはJSONまたはYAMLファイルで宣言できます。これは、ユーザーが手動またはツールで生成および操作するのに便利です。
- 最小限の機能を構築し、必要に応じて追加
YAGNI (You Aint’t Gonna Need It)の原則を適用します。将来必要になると思われるものではなく、現在必要なものを設計および構築します。APIの作成には様々な観点があり、人々は多くの機能を求めています。MVPから始めることで、ノイズに悩まされることなく問題の根本に到達し、コアビルディングブロックとして不可欠な機能を構築できます。
- 開発者第一 (“Developer experience first”)
LoopBackは、開発者による、開発者に向けたものであることを忘れないでください。私たちの最優先事項は、API開発者の仕事を楽にすることです。APIやCLIやGUIなどのユーザーインターフェイスを設計するときは、それらが思考プロセスにとって直感的で自然なものであることを確認したいと考えています。
実装段階
LoopBack 4の最終バージョンへ向けて進んでいる段階を、以下に示します。
- コアのリベースとリライト
-TypeScriptを活用して、コードの品質と生産性を向上
- JavaScriptのオプションの型システムを提供
- 将来のJavaScriptエディションから現在のJavaScriptエンジンに予定されている機能を提供 - 非同期プログラミングモデル/スタイルを統一
- 100%約束ベースのAPI
- 一流の非同期プログラミングスタイルとしての非同期/待機 - 可視性と拡張性を高めるために、IoCコンテナーを実装
- 様々なモジュールにわたるユニバーサルレジストリ
- 依存関係を管理するパターンとしての依存性注入 - 拡張機能のパッケージングモデルとしてコンポーネントを導入
- コンポーネントは、npmモジュールまたはローカルディレクトリにすることが可能
- コンポーネントは拡張機能のリスト全体をカプセル化
- REST / HTTP呼び出しチェーンを実装して、コア設計を検証
- OpenAPI仕様で始まるトップダウンREST API作成を追加
- インバウンドHTTP処理のアクションのビルドシーケンス
- アクションの構成としてシーケンスを導入
- 最も重要なアクションを実装して、REST APIのルーティングと呼び出しを実現 - API関連のビジネスロジックのエントリポイントとしてコントローラーを導入 モデルは、現在のLoopBackアプリケーションの中心的存在で、以下のような複数の役割を持っています
- データモデリング
- API関連のビジネスロジックのアンカー
- 永続性またはサービス呼び出し
- REST HTTP / JSONエンドポイントへのマッピング
- コンポーネントとしての認証
以下を含むコンポーネントとして認証のコア機能を実装
- 認証要件を示すデコレーター
- 認証を処理する
authenticate
アクション - 様々な認証戦略の拡張ポイント
- 統合および構成機能を再構築
- CRUDやキー/値ストアなどのデータアクセスパターンを表すリポジトリを導入
- レガシージャグラーとコネクタを使用して、CRUDおよびKVのリポジトリインターフェースのリファレンス実装を提供
- ジャグラーを個別のモジュールにリファクタリング/リライト
- 入力システム
- モデルと関係の定義
- 検証
- クエリおよび突然変異言語
- 情報元
- リポジトリインターフェイスとデータアクセスの実装
- サービス呼び出しのサービスインターフェイスと実装 - コネクタのインターフェイスとメタデータを定義する - 書き換えコネクタ
- 宣言的なメタデータとブートストラップ LoopBackは、モデル、関係、データソース、コネクター、ACL、コントローラー、リポジトリー、アクション、シーケンス、コンポーネント、ユーティリティー関数、OpenAPI仕様などの一連の成果物を管理します。これらのアーティファクトをコード(apiおよびデコレータ)で記述するプログラム的なアプローチに加えて、JSON / YAMLファイルで宣言できるように、宣言的なサポートを追加したいと思います。
- JSON / YAML形式の新しいドメイン固有言語(DSL)と対応するテンプレートを定義
- プロジェクトレイアウトを定義して、プロジェクトの成果物を整理
- IoCコンテキストを活用して、拡張ポイント/拡張パターンに従ってそのようなアーティファクトのメタデータ/インスタンスを管理
- 各タイプの成果物のライフサイクルおよびシリアル化/逆シリアル化の要件を定義
- ブートコンポーネントを追加して、アーティファクトを検出/ロード/解決/アクティブ化します。ブートプロセスは、ツールとランタイムの両方に合わせて調整が可能
- ツーリング(CLIおよびUI)
- CLIおよびUIツールを以下に追加します。
- Scaffold LoopBack 4アプリケーション
- シーケンス、アクション、コントローラー、リポジトリ、サービス、データソース、モデルなどの成果物を管理
- クラウドネイティブエクスペリエンスを有効化
- コントローラがgRPCサービスとして公開されることを許可
- 他のgRPCサービスとの相互作用を許可
- DockerやKubernetesなどのマイクロサービス展開インフラストラクチャとの統合
- サービスメッシュとの統合
次の図は、LoopBack 4の構成要素をハイレベルに示しています。
スタック内の各機能領域の下に、共通のレイヤーがあることに注意してください。 それでは、LoopBack 4の新しいコア基盤を構築する必要性を調べてみましょう。
新しいコア基盤
中心的な役割
LoopBack自体はすでにモジュール化されています。たとえば、典型的なLoopBack 3.xアプリケーションの依存関係グラフには、次のnpmモジュールがあります。
- loopback
- strong-remoting
- loopback-datasource-juggler
- loopback-connector- *
- loopback-component-explorer
LoopBackは、様々なモジュールにわたって様々なアーティファクトを管理します。以下は、LoopBack 3.xがすぐにサポートする組み込みタイプの成果物のリストです。
- モデルの定義/関係:データモデルとその関係についてを記述
- バリデーション:モデルのインスタンスとプロパティを検証
- モデル構成:モデルを構成し、データソースに接続
- データソース:バックエンドシステムへの接続を構成
- コネクタ:基盤となるバックエンドシステムとの相互作用を実装
- コンポーネント:LoopBackでブートストラップされるモジュールを包括
- リモート処理:JavaScriptメソッドをREST API操作にマッピング
- ACLs:保護されたリソースへのアクセスを制御
- 組み込みモデル:User、AccessToken、Roleなどの事前構築モデルのセットを提供
- フック/インターセプター
- Expressミドルウェア
- リモートフック
- CRUD操作フック
- コネクタフック
- セキュリティ統合
- IDおよびトークン管理
- 認証スキーム
- 様々な認証戦略のためのパスポートコンポーネント
- 様々なローカル/クラウドオブジェクトストレージシステムのストレージコンポーネント
- ローカルファイルシステム
- Amazon S3
- Rackspace
- Azure
- Google Cloud
- OpenStack
- IBMクラウドオブジェクトストレージ
- モバイルプッシュ通知用のプッシュコンポーネント
- iOS
- Android
- 様々なAPIスタイル
- REST
- gRPC
- GraphQL
これらのアーティファクトのメタデータは、LoopBackのナレッジベースを形成して、すべての要素を結合し、一般的なAPIユースケースを処理する機能を構築します。
メタデータとそれらの関係を表現する方法は、LoopBackコア基盤の重要な役割です。このような構成要素を提供・使用されるための一貫した方法を提供する必要があります。
コアの主要成分
LoopBack 4の中核となる基盤は、様々なアーティファクトを、各性質とは別々に管理する役割があります。
- すべてのアーティファクトの可視性とアドレス可能性を提供する、一貫したレジストリ
- 可視性:各アーティファクトには一意のアドレスがあり、URIまたはキーを介してアクセスできます。アーティファクトは、様々なスコープで表示することもできます。
- 拡張性:LoopBackの成果物はタイプごとに管理できます。新しい成果物タイプを導入できます。特定のタイプのインスタンスを追加、削除、または置換できます。拡張ポイント/拡張機能の階層でアーティファクトを整理すると、プロバイダーとコンシューマーが分離されます。
- 依存関係を解決して作成する機能
- 構成可能性:1つのアーティファクトが他のアーティファクトに依存することはよくあります。依存性注入またはサービスロケーターパターンにより、コアは複数のアーティファクトがどのように連携するかを、大幅に簡素化します。
- 拡張機能のパッケージングモデル
- プラグ可能性:拡張機能は、全体として編成および提供できます。拡張機能の開発者が独自のモジュールをバンドルとして作成し、LoopBackアプリケーションにプラグインできるように、パッケージングモデルが必要です。
Expressがバックにある理由
背景
私たちは、Expressのエコシステムの幅広いコミュニティやミドルウェアを活用することができるように、Loopbackを常にExpressの上に構築していました。しかし、それによりLoopbackにはいくつかの課題が残りました。LoopBack 4では、Expressからの移行(そしてExpressなしでフレームワークの構築までも)を検討しましたが、その広大なエコシステムのため、最終的にはExpressに戻りました。
Expressが提供するものとLoopBackのニーズとのギャップは、例えばこのようなものがあります。
- 拡張性の欠如
Expressはミドルウェア経由でのみ拡張可能です。レジストリを公開せず、ミドルウェアやルーターなどのアーティファクトを管理するためのAPIも提供しません。
- 構成可能性の欠如
Expressはコンポーザブルではありません。例えば、
app.use()
は、ミドルウェアを登録する唯一の方法ですが、ミドルウェアの順序は、app.use
の順序によって決まります。 - 宣言的なサポートの欠如
Expressでは、すべてがJavaScriptによって行われます。対照的に、LoopBackは、ベストプラクティスとしての規則とパターンによるAPIの作成と構成を容易にするように設計されています。
ひねりを加え、Expressに戻る
LoopBackの主な目的は、CORSのミドルウェアや静的ファイルサービスなどではなく、データベース、サービスなどとやり取りするAPIの作成を簡単にすることです。LoopBack4の新しいミドルウェアを作成して、「車輪を再発明」は避けたいところでした。
そこでチームは、Express or Koa の活用を検討しました (ただし、ミドルウェアのサポートのみ)。最終的な決定は、上記で特定したギャップを次のように解決し、埋める方法でExpressを使用することでした。
- LoopBackは、 独自のコントローラー/ OpenAPIメタデータ最適化ルーティングエンジンを提供
- Expressは、Expressミドルウェア(CORS、静的ファイルサービス)を使用可能にするためにのみ、適用
- LoopBackは、アクションのシーケンスを使用して、コンポーザブルな方法でレスポンスを作成し、
@loopback/context
をレジストリとして活用します。 詳細については、インバウンドHTTP処理の改善に関するブログ投稿をご覧ください 。
## LoopBack 4の拡張性の詳細
LoopBack 4の拡張性を実現するには、いくつかの重要な柱があります。
Context、サービスを管理するIoCコンテナー 構成を容易にする依存性注入 注釈を使用してメタデータを提供するデコレーター 拡張機能をバンドルするパッケージングモデルとしてのコンポーネント Extending LoopBack 4をご覧ください
- Context : サービスを管理するIoCコンテナー
- Dependency injection : 構成を容易にする
- Decorators : 注釈を使用してメタデータを提供する
- Component : 拡張機能をバンドルするパッケージングモデルとしての機能
詳しくは、 Extending LoopBack 4をご覧ください。
新しいコアの上にLoopBackエクスペリエンスを再構築する
拡張可能な基盤が整ったら、次のアーティファクトで “Eat your own dog food” (自分のシステムを試してみる)ことにより、LoopBack REST APIエクスペリエンスの再構築を開始します。
- シーケンスとアクション:HTTPリクエスト/レスポンスを処理するアクションのシーケンス。
- コントローラー:RESTエンドポイントの背後でAPI操作を実装するメソッドを持つクラス。
- モデル:データモデルの定義。
- リポジトリ:データソースのアクセスパターンのインターフェイス。 機能は次のモジュールによって提供されます。
- @ loopback / rest
-
@ loopback / repository
- シーケンスとアクション: HTTPリクエスト/レスポンスを処理するアクションのシーケンス
- コントローラー: RESTエンドポイントのバックで、API操作を実装するメソッドを持つクラス operations behind REST endpoints.
- Model: データモデルの定義
- Repositories:データソースのアクセスパターンのインターフェイス
各機能は次のモジュールによって提供されています。
アプリケーション開発者向けの例
先に進む前に、LoopBack 4で「hello world」アプリケーションを構築してみましょう。
基本的なHello-World
中級の例
拡張機能の開発者向けの例
既存のものから学ぶ
参照資料
- https://strongloop.com/strongblog/announcing-loopback-next/
- https://www.infoq.com/articles/driving-architectural-simplicity
- https://strongloop.com/strongblog/creating-a-multi-tenant-connector-microservice-using-loopback/
- https://strongloop.com/strongblog/loopback-as-an-event-publisher/
- https://strongloop.com/strongblog/loopback-as-a-service-using-openwhisk/