2年前、Instacartのカスタマーエンジニアリングチームは、顧客対応のアプリケーション用の新しいAPIの開発に着手しました。 従来のAPIである既存のAPIをみてみると、クライアント側で多くのドメインロジックを実装していたため、多くのクロスプラットフォームの重複が発生していました。 これは、機能の構築と出荷に時間がかかり、バグが発生しやすく、すべてのクライアントプラットフォームに一貫してリリースされていないことでした。

私たちは、エンジニアリングチームに最大のテコ(leverage)を与え、より速く動くように支援するアーキテクチャーを見つける機会を得たかったのです。 最終的には、ビュー・モデル・アーキテクチャー(view model architecture)に着手し、新しいAPIのほとんどがビュー・ベースのモデルにするように構造化しました。 ビューモデルアーキテクチャは、非効率性を低減し、私たちのエンジニアリングチームをよりより効果的に活用することを可能にします。

移行を通じて、エンジニアリングの生産性が向上し、一貫性、パフォーマンス、安定性が向上しました。 我々は途中でいくつか学びました。 このブログのシリーズでは、これらをあなたと共有したいと考えています。

Part1では、ビューモデルAPIの概念、それがより良い方法、Instacartで構築した例を簡単に説明します。 最初から始めましょう。

データAPI

Instacartの従来のAPIは標準的なRESTfulデータAPIであり、APIのレスポンスは主にデータモデルを反映しています。 クライアントアプリケーションはこのAPIを消費し、クライアント側で何をレンダリングし、どのようにレンダリングするかを決定するために多くのロジックを構築しました。 これは以下のグラフで表されます。

一見すると、このアプローチは妥当と思われます。 確かに、InstacartのAPIは何年も構造化されています。 APIレスポンスは、単にデータベースにあったものをJSONでダンプしたもので、ほとんどのドメインロジックの実装はクライアントアプリケーションに残りました。 ドメインロジック、つまりビジネスロジックは、ビジネスを実行するために実装したロジックです。 これには、使用可能なアイテムの決定、アイテムの価格設定または注文合計の計算など、あらゆる種類のものが含まれます。

データAPIのアプローチでは、ドメインロジックが各クライアントプラットフォームごとに1回、何度も実装されることに注意してください。 クライアント上でビジネスロジックを実装するということは、3つのプラットフォームすべてで同じロジックを実装する必要があることを意味します。その結果、重複が発生し、効率が悪くなり、バグや矛盾が発生しやすくなります。

さらに悪いことに、通常はサーバー側でビジネスロジックを実装することになります。 トータルで考慮する。 クライアントが提供する量を単純に信用することはできないため、常にサーバー側にロジックを実装したいと考えています。 実際には、同じドメインロジックが4回実装されてしまいます。 これはかなりの工数を要するだけでなく、各プラットフォームで作業しているエンジニアがチームごとに異なる可能性があり、ドメインロジックが一貫性のない、あるいは悪い形で間違って実装される可能性が高くなります。

コードと労力の重複は良いことではありません。 ただし、複数のエンジニア、チーム、プラットフォーム、または言語にまたがって展開された場合の重複があまり明確でないため、クロスプラットフォームの重複が一般的です。 1人のエンジニアがすべてのプラットフォームで作業した場合、同じコードを4回実装することはほとんどありません。 この隠された非効率性は、エンジニアリングの生産性に大きな不利を与えます。

DRY it up!

これを解決するには、クロスプラットフォームのDRYingを実行し、すべてのドメインロジックをバックエンドに移動し、クライアント側のドメインロジックを排除します。 すべてのドメインロジックサーバー側を移動したので、APIレスポンスは主にビューベースになります。 クライアントはドメインロジックを実装するためのデータを必要とせず、ビューデータAPIレスポンスで直接ビューをレンダリングできます。

Model APIの表示

ビューモデルアプローチでは、APIレスポンスはデータではなくビューをモデル化します。 上に示したように、ドメインモデルは、データがどのように表示されるかを決定するView Modelに変換されます。 このビューデータ(view data)は、クライアントがビューをレンダリングするために使用するAPIを介してクライアントに戻されます。 これはMartin FowlerのTwo Step Viewパターンに似ています。ステージ1はビューモデルトランスフォーメーション(変換)であり、クライアントレンダリングはステージ2です。

例えば、アイテムのリストを考えてみましょう。

以下は、クライアント上でレンダリングされるアイテムのリストです。プロデュース部門のスクリーンショットです。 データAPIを使用すると、Departmentモデルと多数のアイテムモデルを返すことがあります。 クライアントは、ドメイン論理を実装してDepartmentをどのようにレンダリングするか、どの部門がプロデュース部門に属するか、そしてどのように項目を適切にソートするかを把握します。

ビューモデルでは、APIレスポンスによってビューがモデル化されるため、レスポンスはクライアントアプリケーションのレンダリングと顧客に表示する物をモデリングします。 この場合、アイテムリスト(item list)と呼ばれるビューモデルを定義します。このモデルには、タイトル、事前ソートされたアイテムの配列、および[詳細を表示(view more)]リンクのラベルアクションがあります。 サーバー上で、DepartmentとそのItemsをItems Listに変換し、APIを介してクライアントに返します。 アイテムリストデータを使用すると、クライアントはDepartmentの内容を知らずにアイテムのリストを表示できます。

Departmentへの商品リストのレスポンスを結ぶ(繋ぐ)ものは何もないので、商品リスト、商品のリストである上記の「あなたの商品」リストなど、商品リスト、関連商品、または任意の商品リストを簡単に再利用することができます 以前に注文した ビューモデルの再利用性は、とりわけ、従来のデータAPIに比べて大きな利点を提供します。

例:価格設定

ビューモデルの利点を示す1つの機能は、アイテムの価格設定です。 時間の経過とともに、通常の価格設定、販売価格設定、ロイヤルティ価格設定など、様々な価格設定バリアントが構築されています。 さらに、クーポン、CPGプロモーション、複雑な小売プロモーション(BOGO)の設定、x%オフの購入、ブランドや製品シリーズのプロモーションの組み合わせなど、さまざまなプロモーションをサポートしています。

データAPIによる価格設定バリアント

従来のデータAPIを使用すると、このようなものになります。 独自のAPIレスポンスを持つ各価格設定バリアント、および各クライアントは、正しい価格設定を実現するためにクライアント側にビジネスロジックを実装する必要があります。

これは理想から遠いです。 価格設定バリアントまたはプロモーションを追加するたびに、4回の実装が必要になります。 その後、更新された各アプリ  は、通常の店舗レビューとリリースサイクルを経なければならず、新しい機能が展開されるまで数週間かかることになります。 ビジネスロジックがすべてのプラットフォーム上で正しく、一貫して実装されるためには、より多くのドキュメント、sync meeting、およびテストが必要となるため、かなりのオーバーヘッドもあります。

クライアント側の作業をしていないすべてのクライアントにプロモーションを行いますか? 価格設定ビューモデルを入力します。
既存のすべての価格設定バリアントがどのようにクライアントアプリケーションにレンダリングされているかを見て、すべての価格設定バリアントとプロモーションのビューをモデル化したレスポンスを作成しました。 価格設定の例は次の通りです。

「価格設定」ビューモデル

この商品は両方とも販売中で、Mix&Matchの一部であり、Buy Nはプロモーションを$ Xオフにします。これをサポートするためにAPIレスポンスを構成することがどれほど複雑であるか、またこれが動作するにはどれくらいのクライアント作業が必要になるかを考慮してください。 価格設定ビューモデルはこれを完全に排除します。この複雑な機能のためにクライアントアプリケーションに必要なドメインロジックはありません。 ロジックはすでにサーバー側で事前にレンダリングされており、クライアントアプリケーションは返された内容を単に提示します。

ビューモデルAPIによる価格設定

価格設定ビューモデルを使用すると、APIを更新して、すべての価格設定バリアントおよびプロモーションに対して同じ価格設定レスポンスを返すことができます。クーポン機能の後にAPIとクライアントアプリで「価格設定」ビューモデルを実装しました。その結果、点線の下にあるすべての新しいプロモーションがクライアント側の作業なしでローンチされました。

これらの新しいプロモーションには同じ価格設定レスポンスが再利用されるため、価格設定ビューモデルをサポートする既存のクライアントアプリは、アプリのアップデートを一切経ずに、APIのデプロイ直後にこれらの新しいプロモーションをサポートすることができます。

ビューモデルはどのように優れていますか?


私たちの経験では、ビューモデルAPIのアプローチは、生産性、一貫性、パフォーマンス、および安定性の4つのカテゴリで改善されました。

生産性

ビューモデルアプローチは、クライアント間の重複作業を削減し、ドメインロジックを実装するのではなく、ビルドビューに集中することができるため、エンジニアリング効率を大幅に向上させることができます。

ビューモデルは、多くの機能で再利用可能なことが多く、再利用するとクライアント側の作業がほとんどまたはまったくなく、すべてのクライアントに機能を提供できます。 私たちのような3つのクライアントプラットフォームをお持ちの場合、これにより1/4の作業でフィーチャーを出荷でき、効果的に全員を4倍のエンジニアにすることができます。

一貫性

ビューモデルは、3つの方法で整合性を向上させます。

•実装の一貫性
すべてのドメインロジックは、ビューモデルレスポンスを介してクライアントからアブストラクトすることができるため、クライアントアプリケーション間でドメインロジックが一貫して実装されない可能性を排除する。

•デザインの一貫性
ビューのモデルレスポンスは、アプリ内およびすべてのアプリにわたってUIコンポーネント間で一貫したデザインを促進します。 既存のビューモデルを使って新しいフィーチャを作成するのではなく、それがはるかに簡単で迅速です。

•機能セット一貫性
クライアントアプリケーションが特定のビューモデルのレスポンスをサポートしている限り、クライアントは特定のビューモデルの今後の追加使用をすべてサポートすることもできます。 これにより、エンジニアリングリソースの不足のために特定のクライアントでサポートされていない機能の数が減少し、すべてのクライアントで常に使用可能な機能の数が向上します。

パフォーマンス

ビューモデルのレスポンスには、ドメインロジックに必要なデータが含まれなくなりました。これにより、レスポンスのペイロードがほぼ常に削減されます。 これにより、特にモバイルクライアントの場合のように、信頼性の低い接続のクライアントの場合は、アプリのレスポンスが向上します。 私たちの経験では、特定のエンドポイントのペイロードサイズを10倍以上に減らすことができました。これは、顧客にとって大きな改善です。

安定

ビューモデルレスポンスは、クライアントアプリケーションの安定性を大幅に向上させることもできます。 ロジックサーバー側を移動すると、多くのクライアントサイドコードが削除され、クライアントアプリケーションのバグの可能性が減少します。最高のコードはコードをなくすことです。

すべてのドメインロジックサーバーサイドを持つということは、テストを書くためのコードのコピーを1つしか持たないことを意味し、大きなテストカバレッジ(網羅率)を持つ可能性を高め、バグのないコードを書くことになります。

全体として、ビューモデルAPIで大きなメリットを経験しました。これは、お客様と私たちにとって共通のメリットです。 アプリは、より速く、より安定しており、一貫性があり、完全に機能しています。 このすべては、高いエンジニアリング効率と生産性で実現しました。 私たちはより速く動いて、より少ないものを打ち破ることができます。

結論


私たちの経験では、ビューモデルAPIへの移行により、エンジニアリングの生産性が大幅に向上しました。 以前は「ウェブのみ」であった多くの機能がすべてのクライアントで利用可能になりました。 また、クライアント側の作業がほとんどまたはまったくなく、通常のアプリ更新サイクルを経ることなく、多くの新機能をより迅速に出荷することができました。

transpiling codeReact Nativeなどのような、クライアント間でコードを共有する方法は他にもたくさんあります。 私はエンジニアリングアーキテクチャーが組織の構造を反映しているべきだと大変信じています。 ネイティブアプリ(iOSまたはAndroid)エンジニアよりもフルスタックおよびバックエンドのエンジニアが大幅に多いため、ビューモデルのアプローチは、ユニークなチームサイズとメーキャップのバランスを崩しません。 これにより、ネイティブのアプリエンジニアは、完全なネイティブビューを備えた良いクライアントアプリケーションの作成に集中できます。また、APIをシンプルで簡単に保ちながら、新しいフレームワークを必要としません。

ここ2年間で、私たちは、記事で使用されている例をはるかに上回るビューモデルを採用しました。 このブログシリーズのpart2では、ほぼすべてのアプリが構築されているページベースのビューモデルレスポンスであるContainers and Modulesを紹介します。 これらの新しいコンセプトは、ビューモデルのアイデアを基にして、メリットを拡大し、エンジニアの活用度をさらに高めます。

私はあなたがこの記事を面白いと思ったことを願っています このような記事をもっと読みたい場合は、Instacartの技術ブログを参照してください。 また、エンジニアリングチームを構築しています。素晴らしいAPIを構築したり、魔法のコンシューマアプリのエクスペリエンスを作成したり、インフラストラクチャを拡張したり、何かエンジニアリングすることに興味があるなら、私たちは採用しています🙂

My thanks to Dominic Cocchiarella, Min Kim, Dan Hsiao, Michael Scheibe, and Kaushik Gopal (with glasses) for reading a draft of this post.

タイトル:Building Instacart’s view model API — Part 1: Why view model?

作者:Peter Lin

原文URL:https://tech.instacart.com/building-instacarts-view-model-api-part-1-why-view-model-4362f64ffd2a

今すぐシェアしよう!
今すぐシェアしよう!