REST APIがファサードデザインパターンに従っていない理由


9

REST [api]構造とOOモデルを比較すると、次のような類似点があります。

どちらも:

  • データ指向ですか

    • REST =リソース
    • OO =オブジェクト
  • データを取り巻く操作

    • REST =リソースをVERBS(Get、Postなど)で囲みます
    • OO =カプセル化によってオブジェクトの周りの操作を促進する

ただし、適切なOOプラクティスは、たとえばファサードパターンを適用しようとするときにREST APIに常に依存しているわけではありません。RESTでは、すべてのリクエストを処理する1つのコントローラーがなく、内部オブジェクトの複雑さを隠しません。

2つの概念間の単純なオブジェクト関係

OOとRESTの類似点

それどころか、RESTは、少なくとも2つの形式で、リソースとその他のすべての関係のリソース公開を促進します。

  1. リソース階層関係を介して(id 43の連絡先はアドレス453で構成されます): /api/contacts/43/addresses/453

  2. REST json応答のリンクを介して:

>> GET /api/contacts/43
<< HTTP Response {
   id: 43, ...
   addresses: [{
      id: 453, ...
   }],
   links: [{
      favoriteAddress: {
          id: 453
      }
   }]
}

objectAによって隠された基本的な複雑さ

OOに戻ると、ファサードの設計パターンLow Couplingは、objectAとその「objectBクライアント」の間、およびHigh CohesionこのobjectAとその内部オブジェクト構成(objectCobjectD)を尊重します。とをObjectAのインターフェースは、これは、許可に制限の影響に現像剤をObjectBObjectAに(内部変化ObjectCに及びobjectD長いほど)、ObjectAにする API(操作)が依然として尊重されます。

RESTでは、データ(リソース)、関係(リンク)、および動作(動詞)がさまざまな要素に展開され、Webで利用できます。

RESTで遊んでいると、クライアントとサーバーの間のコード変更に常に影響があります。それHigh Couplingは、Backbone.jsリクエストとLow Cohesionリソースの間で行っているためです。

RESTリンクによって促進されるBackbone.js javascript applicationRESTリソースおよび機能」のディスカバリーに対処する方法を理解できませんでした。WWWはマルチサーバーによって提供されることを意図しており、OO要素はその中の多くのホストによって処理されるように展開する必要があることを理解していますが、アドレスとの連絡先を示すページを「保存」するような単純なシナリオでは、私は結局:

GET /api/contacts/43?embed=(addresses)
[save button pressed]
PUT /api/contacts/43
PUT /api/contacts/43/addresses/453

これにより、ブラウザーアプリケーションで保存アクションのアトミックトランザクションの責任を移動することになりました(2つのリソースを個別にアドレス指定できるため)。

これを念頭に置いて、開発を簡略化できない場合(Facadeデザインパターンは適用不可)、クライアントをより複雑にする場合(トランザクションアトミック保存の処理)、RESTfulであることの利点はどこにありますか?


1
わかりました。2つのREST呼び出しを使用して、「埋め込み」(構成)リンクアドレスで連絡先を更新する必要があると述べています。連絡先の更新を処理するファサードがあります。PUT /api/contacts/43内部オブジェクトへの更新をカスケードすることの問題は何ですか?私はこのように設計された多くのAPIを持っていました(マスターURLは「全体」を読み取り/作成/更新し、サブURLは断片を更新します)。(パフォーマンス上の理由から)変更が必要ない場合は、アドレスを更新しないようにしてください。
Anthony Accioly 2013年

@AnthonyAccioly、あなたは正しく理解しました。画像をいくつか追加して、質問を明確にしようとしました。あなたの提案は良いですし、それは私が得た結論でもあります。手動でリクエストを制御し、埋め込みオブジェクトを使用して、アトミックな更新を維持するためのリクエストを1つだけ送信します。それでも、RESTのすべてのものが、モデルをフラット化する(多くのコントローラーを意味する)ことによって、OOの品質や強制(カプセル化など)から遠ざかる理由。ソリューションを使用すると、1つのアトミックアップデートが提供されます。ソリューションを使用しないことは、開発者に新しい責任をもたらし、APIに彼がそれを実行するのを防ぐためのルールがありません。
アラン

ただ注意:あなたが言及した「リソース階層関係」は、関係情報を識別子(この場合はURL)にエンコードすることを決定する方法の問題です。この情報の説明がRESTの一部であるか、それが促進するものであるかはわかりませんが、システムのURLを思いついたときに自分で決定するだけです。そうでないと思われる場合、RESTの一部としてこの問題について議論しているRoy Fieldingの参照がありますか?
チアゴ・シウバ

回答:


7

オブジェクトは、データの周りではなく、一貫した行動の周りにのみ正しく構築されていると思います。私は挑発し、オブジェクト指向の世界ではデータはほとんど無関係であると言います。実際、「ログシンク」などのデータを決して返さないオブジェクトや、たとえば、統計プロパティを計算する場合など、渡されたデータを決して返さないオブジェクトが存在する可能性があり、時々一般的です。

PODS(構造にすぎない)と、振る舞いを持つ実際のオブジェクト(Contacts例のクラスのような)を混同しないようにしましょう1

PODSは基本的に、リポジトリやビジネスオブジェクトと通信するために使用される便利な機能です。これにより、コードをタイプセーフにすることができます。それ以上でもそれ以下でもありません。一方、ビジネスオブジェクトは、データの検証、格納、計算の実行などの具体的な動作を提供します。

つまり、動作は「凝集度」2を測定するために使用するものであり、最上位の連絡先を操作するメソッドのみを表示し、アドレスを操作するメソッドを表示しない場合でも、オブジェクトの例にある程度の凝集があることを確認するのは簡単です。

RESTについては、RESTサービスをデータリポジトリとして見ることができます。オブジェクト指向のデザインとの大きな違いは、デザインの選択肢が(ほぼ)1つしかないことです。4つの基本的なメソッド(HEADたとえば、を数えるとさらに多く)があり、もちろんURIには多くの余裕があるので、気の利いたことができます多くの IDを渡し、より大きな構造を取り戻すようなものです。渡されるデータと実行される操作を混同しないでください。結束と結合は、データではなくコードに関するものです

明らかに、RESTサービスは凝集度が高く(リソースと対話するすべての方法が同じ場所にあります)、結合度が低い(すべてのリソースリポジトリは他のリソースの知識を必要としません)。

ただし、基本的な事実は変わりませんが、RESTは基本的にデータの単一のリポジトリパターンです。これは、「雑談」のコストが高い、低速の媒体を介した簡単なアクセスを中心に構築されたパラダイムであるため、結果をもたらします。通常、クライアントはできるだけ少ない操作を実行する必要があるが、同時に必要なデータのみを受信する。これにより、送り返すデータツリーの深さが決まります。

(正しい)オブジェクト指向設計では、重要なアプリケーションは、たとえば合成など、はるかに複雑な操作を実行します。RESTはAPIプロトコルですが、OODはユーザー向けのアプリケーション全体を構築するために使用されるため、データを使用してより専門的な操作を実行するためのメソッドを使用できます。これが、凝集度と結合度の測定がOODでは基本的であるがRESTではほとんど重要でない理由です。

OOの概念を使用してデータ設計分析することは、データを測定するための信頼できる方法ではないことは今や明らかです。それは、リンゴとオレンジを比較するようなものです!

実際、RESTfulであることの利点は、(ほとんどの場合)上で概説したものであることがわかります。これは、低速なメディアを介した単純なAPIの良いパターンです。これは非常にキャッシュ可能で、シャーディング可能です。雑談などをきめ細かく制御します。

これがあなたの(かなり多面的な)質問に答えることを願っています:-)


1この問題は、オブジェクトリレーショナルインピーダンスミスマッチと呼ばれるより大きな問題の一部です。ORMの支持者は通常、データ分析と動作分析の類似点を模索している陣営にいますが、ORMはインピーダンスの不一致を実際には解決していないようで、リークの多い抽象化と見なされているため、最近の批判にさらされています。

2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)


その質問は、これらの側面の蓄積に基づく「間違った」結論に対応しているため、特定のポイントを特定するために、多くの側面で私の質問を分解するのに苦労しました。多くのコメントであなたのポイントに答えようと思います。
2013年

[text 1]「データ」という言葉を使用して、OOおよびRESTの世界から抽象化しました。OOのプロパティとRESTのデータ構造を抽象化するには、どの単語を使用しましたか?
アラン

@Alainの「データ」は問題ありませんが、私のポイントはPODSとビジネスオブジェクトを混同しないことです。OODについて話すときは、通常、2番目について話します。1つ目は便利で、辞書や構造体、タプルと同じくらい簡単に考えることができます。
Sklivvz 2013年

はい、同意します。モデルの保存に単純なjson構造を使用する場合、Backbone.jsを使用します。これは、テキストが私の実際のコーディング経験を反映する場所です。
2013年

[text 3]これは私にとって新しいものです。凝集度は、特定の関係を使用する方法の数によって測定されると思いました...私はそれをあなたの見方で見る方が好きです。
2013年

1

これを念頭に置いて、開発を簡略化できない場合(Facadeデザインパターンは適用不可)、クライアントをより複雑にする場合(トランザクションアトミック保存の処理)、RESTfulであることの利点はどこにありますか?

「RESTfulであることの利点はどこにあるのか」に対する答え。ここで徹底的に分析および説明されています:http : //www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

ただし、この質問での混乱は、RESTの特性とその対処方法ではなく、サンプルシステム用に作成したURLの設計がRESTfulであることと関係があるということです。結局のところ、RESTにはリソースと呼ばれるものがあり、参照する必要があるものには識別子を提供する必要があると述べていますが、たとえば、ERモデルのエンティティが作成したURLと1対1で対応している必要はありません。 (URLがモデル内のER関係のカーディナリティをエンコードする必要はありません)。

連絡先と住所の場合、これらの情報を抽出して、たとえば異なるリレーショナルDBテーブルに保存したい場合でも、PUTまたはPOSTしたときに、これらの情報を1つの単位として一緒に表すリソースを定義できます。 。


1

ファサードは「クラッジ」だからです。「API抽象化」と「APIチェーン」を見てください。APIは、I / Oとリソース管理の2つの機能セットの組み合わせです。ローカルでは、I / Oは問題ありませんが、分散アーキテクチャ(つまり、プロキシ、APIゲート、メッセージキューなど)内ではI / Oが共有されるため、データと機能が重複して絡み合います。これは、建築の分野横断的な懸念につながります。これは既存のすべてのAPIを悩ませます。

これを解決する唯一の方法は、APIのI / O機能をpre / postハンドラー(Spring / GrailsのhandlerIntercepterやRailsのフィルターなど)に抽象化して、機能をモナドとして使用し、インスタンスと外部で共有できるようにすることですツーリング。リクエスト/レスポンスのデータもオブジェクトで外部化する必要があるため、共有および再ロードすることもできます。

http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining


0

RESTサービス、または一般的にあらゆる種類のAPIを理解している場合は、クライアントに公開されてコントローラーがコントローラーをプログラムできるようにする追加のインターフェースと同じように、突然簡単になります。このサービスは、ビジネスロジックの上の追加レイヤーにすぎません。

言い換えると、上の図のように、複数のコントローラー間でビジネスロジックを分割する必要はありません。さらに重要なこととして、分割する必要はありません。データの交換に使用されるデータ構造は、内部で使用するデータ構造と一致する必要はなく、まったく異なる場合があります。

最先端の技術であり、広く受け入れられていますが、任意のビジネスロジックをUIコードに組み込むことは悪い考えです。しかし、すべてのUIは、背後にあるビジネスロジックを制御するための一種のインターフェイス(I in UI)にすぎません。したがって、BizロジックをRESTサービスレイヤーやその他のAPIレイヤーに配置することも悪い考えであることは明らかです。

概念的には、UIとサービスAPIの間にそれほど大きな違いはありません。


レイヤーの概念には同意しますが、「それを介してコントローラーをプログラムする」とはどういう意味ですか?
2013年

1
コントローラー自体が実際のサービスであることを強調したいと思います。全体を包み込むインターフェースは、何かを達成するための単なる手段です。何らかの方法で、ラップされた機能へのアクセスを容易にするためのインターフェイスが存在します。GUIは人間のユーザーのためにこれを行い、サービスAPIはクライアントによって使用されます。どちらの対象読者も、インターフェースの背後にあるもので何かを実現したいと考えています。「プログラム」はそのための最良の言葉遣いではないかもしれませんが、「コントローラーを制御する」はどちらもぎこちなく聞こえます;-)
JensG
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.