WebアプリケーションのAPIを開発するために、RESTとJSON-RPCのどちらかを選択しようとしています。彼らはどのように比較しますか?
2015年更新:クライアントとサーバーの両方が理解する既存の成熟したHTTPプロトコルをAPIで利用できるため、RESTを開発してWeb / HTTPで提供されるAPIを使用する方が簡単であることがわかりました。たとえば、応答コード、ヘッダー、クエリ、投稿本文、キャッシング、およびその他の多くの機能を、追加の作業や設定なしでAPIで使用できます。
WebアプリケーションのAPIを開発するために、RESTとJSON-RPCのどちらかを選択しようとしています。彼らはどのように比較しますか?
2015年更新:クライアントとサーバーの両方が理解する既存の成熟したHTTPプロトコルをAPIで利用できるため、RESTを開発してWeb / HTTPで提供されるAPIを使用する方が簡単であることがわかりました。たとえば、応答コード、ヘッダー、クエリ、投稿本文、キャッシング、およびその他の多くの機能を、追加の作業や設定なしでAPIで使用できます。
回答:
RPCの基本的な問題は結合です。RPCクライアントは、いくつかの方法でサービス実装に密接に結合され、クライアントを壊さずにサービス実装を変更することは非常に困難になります。
一方、RESTスタイルでは、表現(HTTPヘッダー+表現)に制御情報を含めることで、クライアントを簡単にガイドできます。例えば:
REST側には、さらに多くの違いと利点があります。
私は問題を詳細に調査し、純粋なRESTは制限が多すぎ、RPCが最善であると判断しました。ただし、私のアプリのほとんどはCRUDアプリです。RESTに固執する場合、最終的に頭を悩ませることになり、特別な目的のために、必要な別のメソッドをAPIに簡単に追加する方法を疑問に思います。多くの場合、RESTでこれを行う唯一の方法は、そのための別のコントローラーを作成することです。これにより、プログラムが過度に複雑になる場合があります。
RPCを決定する場合の唯一の違いは、URIの一部として動詞を明示的に指定していることです。これは明確で、一貫性があり、バグが少なく、本当に問題ありません。特に、単純なCRUDをはるかに超えるアプリを作成する場合、RPCが唯一の方法です。RESTful主義者には別の問題があります。HTTPでHTTP POST、GET、PUT、DELETEは明確な意味を持っていますが、RESTによって他の意味に変換されています。
プログラミングにおいて、私はずっと前に、1つのことを使用して2つのことをしようとすると、いつか思い付き、あなたに噛み付くことに気づきました。メソッドの必要に応じてデータを自由に送受信できるので、POSTをほぼすべてのアクションで使用できるようにしたいと思います。全世界をCRUDに適合させることはできません。
まず、HTTP-RESTは「表現状態転送」アーキテクチャです。これは多くの興味深いことを意味します:
2番目に、HTTP-RESTはHTTPに完全に準拠しているため(前の部分の「安全」と「べき等」を参照)、HTTPライブラリ(既存のすべての言語に存在)とHTTPリバースプロキシを再利用できるため、ゼロ行のコードで高度な機能(キャッシュ、認証、圧縮、リダイレクト、リライト、ロギングなど)を実装する機能。
最後に重要なことですが、HTTPをRPCプロトコルとして使用することは、HTTP 1.1の設計者(およびRESTの発明者)によると大きなエラーです:http : //www.ics.uci.edu/~fielding/pubs/dissertation/evaluation。 htm#sec_6_5_2
CREATE CUP
含まれているであろうと、他のよりも、INSERT COIN
、SELECT COFFEE
、SELECT SUGAR
、とSTART
。2番目のAPIでは、マシンの状態に依存するため、プロシージャコールのシーケンスに注意する必要があります。
すばらしい答え-いくつかのコメントを明確にしたかっただけです。JSON-RPCはすばやく簡単に使用できますが、前述のようにリソースとパラメーターは密結合されており、GET / POSTを使用して動詞(api / deleteUser、api / addUser)に依存する傾向があります。RESTは疎結合リソース(api /ユーザー)HTTP REST APIでは、いくつかのHTTPメソッド(GET、POST、PUT、PATCH、DELETE)に依存しています。RESTは、経験の浅い開発者にとっては実装が少し難しいですが、スタイルは今やかなり一般的な場所になり、長期的にははるかに柔軟になっています(APIの寿命を延ばしています)。
リソースが密結合されていないことに加えて、RESTを使用すると、単一のコンテンツタイプへのコミットを回避できます。つまり、クライアントがXML、JSON、またはYAMLでデータを受信する必要がある場合-システムに組み込まれている場合、 content-type / acceptヘッダーを使用してそれらのいずれかを返します。
これにより、新しいコンテンツタイプやクライアント要件をサポートするのに十分なAPIを維持できます。
しかし、RESTをJSON-RPCから本当に分離しているのは、慎重に検討された一連の制約に従っているため、アーキテクチャの柔軟性が確保されていることです。これらの制約には、クライアントとサーバーが互いに独立して進化できること(クライアントのアプリケーションをめちゃくちゃにすることなく変更を加えることができること)の保証、呼び出しがステートレス(状態はハイパーメディアによって表される)、インタラクション用の統一されたインターフェースが提供されることなどが含まれます。 APIは階層化システムで開発され、応答はクライアントによってキャッシュ可能です。コードをオンデマンドで提供するためのオプションの制約もあります。
ただし、これらすべてについて、ハイパーメディア(APIのナビゲートに役立つ応答に埋め込まれたハイパーテキストリンク)が組み込まれていないため、MOST APIは(Fieldingによると)RESTfulではありません。そこにあるほとんどのAPIはRESTに似ていますが、RESTのほとんどの概念に従っていますが、この制約を無視します。しかし、ますます多くのAPIがこれを実装しており、ますます主流のプラクティスになっています。
これにより、ハイパーメディアドリブンAPI(Stormpathなど)がクライアントをURIに転送する(何らかの変更があった場合、特定のケースではマイナスの影響なしにURIを変更できる)ため、RPC URIと同様に、静的。RPCでは、これらのさまざまなURIを広範囲に文書化し、それらが相互に関連してどのように機能するかを説明する必要もあります。
一般的に、長持ちする拡張可能で柔軟なAPIを構築する場合は、RESTが適しています。そのため、99%の確率で進むべき道だと思います。
がんばって、マイク
IMO、重要なポイントは、アクションとリソース指向です。RESTはリソース指向であり、CRUD操作によく適合し、その既知のセマンティクスにより最初のユーザーにある程度の予測可能性が提供されますが、メソッドまたはプロシージャから実装すると、リソース中心の世界への人工的な翻訳を提供する必要があります。一方、RPCは、CRUD対応のリソースセットではなく、サービスを公開するアクション指向のAPIに最適です。
間違いなくRESTの方が人気があります。APIをサードパーティに公開したい場合、これは間違いなくいくつかのポイントを追加します。
そうでない場合(たとえば、SPAでAJAXフロントエンドを作成する場合)、RPCを選択します。特に、JSON-RPCは、記述言語としてJSONスキーマと組み合わされ、ユースケースに応じてHTTPまたはWebソケットを介して転送されます。
JSON-RPCは、同期または非同期のRPCで使用される要求と応答のJSONペイロードを定義するシンプルでエレガントな仕様です。
JSONスキーマは、JSONデータの記述を目的としたJSONベースのフォーマットを定義するドラフト仕様です。JSONスキーマを使用してサービスの入力メッセージと出力メッセージを記述することにより、使いやすさを損なうことなくメッセージ構造に任意の複雑さを持たせることができ、サービス統合を自動化できます。
トランスポートプロトコル(HTTPとWebソケット)の選択はさまざまな要因によって異なり、HTTP機能(キャッシュ、再検証、安全性、べき等、コンテンツタイプ、マルチパートなど)が必要か、アプリケーションを交換する必要があるかが最も重要です。高頻度でのメッセージ。
これまでは、この問題に対する私の個人的な意見が非常に多かったのですが、今、これらの行を読んでいるJava開発者にとって本当に役立つもの、昨年疑問に思っている同じ質問から生まれた、昨年中に取り組んできたフレームワーク:
ここにライブデモがあり、機能テスト用の組み込みリポジトリブラウザー(JSONスキーマに感謝)と一連のサンプルサービスが表示されています。
それが仲間に役立つことを願っています!
ナチョ
モデルとGET / POST / PUT / DELETEパターンのみでサービスが正常に機能する場合は、純粋なRESTを使用してください。
HTTPはもともとステートレスアプリケーション用に設計されていることに同意します。
しかし、WebSocket(多くの場合、ステートフル性を意味する)を使用する必要がある、現代的でより複雑な(!)リアルタイム(Web)アプリケーションの場合、両方を使用しないのはなぜですか?JSON-RPC over Websocketsは非常に軽量なので、次の利点があります。
サーバー側のAPIのみを設計しているため、RESTモデルの定義から始め、後で必要に応じてJSON-RPCサポートを追加し、RPC呼び出しの数を最小限に抑えます。
(そして括弧の乱用については申し訳ありません)
私は過去にRESTの大ファンであり、紙上でのRPCよりも多くの利点があります。クライアントにさまざまなコンテンツタイプ、キャッシュ、HTTPステータスコードの再利用を提示したり、APIを介してクライアントをガイドしたり、ほとんど説明がない場合はドキュメントをAPIに埋め込んだりできます。
しかし、私の経験では、実際にはこれは長続きせず、代わりにすべてを正しくするために多くの不必要な作業を行っています。また、HTTPステータスコードはドメインロジックに正確にマッピングされないことが多く、コンテキストでの使用は少し強制されているように感じられます。しかし、私の意見では、RESTについて最悪のことは、リソースとリソースが許可する相互作用を設計するために多くの時間を費やすということです。そして、APIにいくつかの主要な追加を行うときはいつでも、新しい機能を追加するための優れたソリューションを見つけて、まだ隅々まで設計していないことを願っています。
ほとんどの場合、APIをリモートプロシージャコールのセットとしてモデル化する方法については、完全に明確で明確なアイデアを持っているため、これは時間の浪費のように感じることがよくあります。そして、RESTの制約内で問題をモデル化するためにこのすべての努力を終えた場合、次の問題はクライアントからそれを呼び出す方法ですか?私たちのプログラムはプロシージャの呼び出しに基づいているため、優れたRPCクライアントライブラリの構築は簡単で、優れたRESTクライアントライブラリの構築はそれほど多くはありません。ほとんどの場合、サーバー上のREST APIからクライアントの一連のプロシージャにマップします。図書館。
このため、今日のRPCは、よりシンプルで自然に感じられます。私が実際に見逃しているのは、自己記述的で相互運用可能なRPCサービスを簡単に作成できる一貫したフレームワークです。したがって、私は自分のプロジェクトを作成して、RPCを自分で使いやすくする新しい方法を試してみました。おそらく他の誰かもそれを便利だと思っています:https : //github.com/aheck/reflectrpc
Richardsonの成熟度モデルによると、問題はRESTとRPCではなく、どれくらいのRESTが必要かということです。
このビューでは、REST標準への準拠は4つのレベルに分類できます。
REST標準の作成者によると、レベル3のサービスのみをRESTfulと呼ぶことができます。ただし、これはコンプライアンスの指標であり、品質ではありません。計算を行うリモート関数を呼び出すだけの場合は、応答に関連するハイパーメディアリンクを含めることはおそらく意味がなく、使用されるHTTP動詞に基づく動作の区別も意味がありません。したがって、そのような呼び出しは本質的にRPCに似たものになる傾向があります。ただし、コンプライアンスレベルが低くても、必ずしもステートフルであること、またはカップリングが高いことを意味するわけではありません。おそらく、REST対RPCではなく、できるだけ多くのRESTを使用する必要がありますが、それ以上は使用しないでください。RESTfulコンプライアンス標準に合わせるためだけにアプリケーションをねじらないでください。
JSON RPCが選ばれる理由:
REST APIの場合、必要になる可能性のある機能/メソッドごとにコントローラーを定義する必要があります。その結果、クライアントにアクセス可能にしたいメソッドが10個ある場合、クライアントのリクエストを特定のメソッドにインターフェースするために10個のコントローラーを作成する必要があります。
別の要因は、メソッド/機能ごとに異なるコントローラーがある場合でも、クライアントはPOSTまたはGETを使用するかどうかを覚えておく必要があることです。これは事態をさらに複雑にします。さらに、POSTを使用する場合は、データを送信するために、リクエストのコンテンツタイプを設定する必要があります。
JSON RPCの場合、ほとんどのJSONRPCサーバーはPOST HTTPメソッドで動作し、コンテンツタイプは常にapplication / jsonであるため、処理は大幅に簡略化されます。これにより、クライアント側で適切なHTTPメソッドとコンテンツ設定を使用することを覚えておく必要がなくなります。
サーバーがクライアントに公開したいさまざまなメソッド/機能に個別のコントローラーを作成する必要はありません。
RESTを選ぶ理由:
サーバーがクライアント側に公開したいさまざまな機能に個別のURLがあります。その結果、これらのURLを埋め込むことができます。
これらの点のほとんどは議論の余地があり、人の必要性に完全に依存しています。
いつものように、それは依存する...
RESTには広範なパブリックサポートの大きな利点があり、これは多くのツールと本を意味します。さまざまな組織の多数のコンシューマーが使用するAPIを作成する必要がある場合、それが唯一の理由である方法です。それが人気があるからです。プロトコルとして、コマンドをURL / verb / responseにマップする完全に異なる方法が多すぎるため、これは完全な失敗です。
したがって、バックエンドと通信する必要がある単一ページのWebアプリを作成する場合、RESTは複雑すぎると思います。この状況では、アプリとAPIを一緒に進化させることができるため、長期的な互換性について心配する必要はありません。
単一ページのWebアプリのRESTを始めたことがありますが、Webアプリとサーバーの間の細かいコマンドがすぐに気が狂いました。パスパラメータとしてエンコードする必要がありますか?体に?クエリパラメータ?ヘッダー?URL /動詞/応答の設計後、この混乱をJavascriptでコーディングし、デコーダーをJavaでコーディングしてから、実際のメソッドを呼び出す必要がありました。このためのツールはたくさんありますが、ドメインコードでHTTPセマンティクスを取得しないようにするのは非常にトリッキーです。(凝集)
中程度の複雑なサイト用のSwagger / OpenAPIファイルを作成して、そのファイル内のリモートプロシージャを記述する単一のJavaインターフェースと比較してください。複雑さの増加は驚異的です。
そのため、単一ページのwebappをRESTからJSON-RPCに切り替えました。aサーバー上のJavaインターフェースをエンコードする小さなライブラリーを開発し、それをブラウザーに出荷しました。これにより、ブラウザーで、各関数のpromiseを返すアプリケーションコードのプロキシが作成されました。
繰り返しになりますが、RESTは有名であり、そのため十分にサポートされているという理由だけでその位置を占めています。根底にある無国籍資源の哲学と階層モデルを認識することも重要です。ただし、これらの原則はRPCモデルでも同様に簡単に使用できます。JSON RPCはHTTP経由で機能するため、この領域ではRESTと同じ利点があります。違いは、これらの原則にうまく対応しないこれらの関数に必然的に出くわしたとき、多くの不必要な作業を強いられないことです。
RESTはHTTPと緊密に結合されているため、HTTP経由でAPIを公開するだけの場合、RESTはほとんどの(すべてではない)状況に適しています。ただし、メッセージングやWebソケットなどの他のトランスポートを介してAPIを公開する必要がある場合、RESTは適用されません。
RESTとJSON-RPCの間でJSON-RPCを選択して、理解しやすいWebアプリケーション用のAPIを開発することをお勧めします。メソッド呼び出しと通信へのマッピングが簡単に理解できるため、JSON-RPCが推奨されます。
最も適切なアプローチの選択は、制約または主な目的に依存します。たとえば、パフォーマンスが主要な特性である限り、JSON-RPC(たとえば、ハイパフォーマンスコンピューティング)を使用することをお勧めします。ただし、主な目的が、他の人に推論される汎用インターフェースを提供するために不可知論であることである場合は、RESTに進むことをお勧めします。両方の目標を達成する必要がある場合は、両方のプロトコルを含めることをお勧めします。
RESTをJSON-RPCから実際に分割するという事実は、慎重に検討された一連の制約を追跡し、アーキテクチャの柔軟性を確認することです。制約は、クライアントとサーバーが互いに独立して成長できること(クライアントのアプリケーションに影響を与えずに変更を加えることができること)、呼び出しがステートレス(状態がハイパーメディアと見なされる)、均一であることを保証することを必要としますインタラクションのためのインターフェースが提供され、APIは階層化システムで拡張されます(Hall、2010)。JSON-RPCは迅速かつ簡単に使用できますが、前述のように、リソースとパラメーターは密結合されており、GET / POSTを使用して動詞(api / addUser、api / deleteUser)に依存する可能性が高く、RESTは疎結合リソース(api / users)HTTPで。REST APIは、GET、PUT、POST、DELETE、PATCHなどのいくつかのHTTPメソッドに依存しています。
JSON(JavaScript Object Notationと表記)は軽量のデータ交換フォーマットであり、人間は読み書きが簡単です。マシンが解析して生成するのは手間がかかりません。JSONは完全に言語に依存しないテキスト形式ですが、C#、C、C ++、Java、Perl、JavaScript、Python、その他多数の言語で構成される言語ファミリのプログラマーが知っている慣習を実践しています。このようなプロパティにより、JSONは完全なデータ交換言語になり、選択するのに適しています。
JSON-RPCを「動詞なし」(メソッドなし)で使用し、sendo ID、パラメーター、エラーコード、警告メッセージに必要な最小限の標準化を維持できます。JSON-RPC標準は、「RESTになることはできません」とは言わず、基本的な情報をパックする方法のみを述べています。
「REST JSON-RPC」が存在します!最小限の情報パッキングのための「ベストプラクティス」を備えたRESTであり、シンプルで強固なコントラクトを備えています。
(この回答と教訓的な文脈から)
RESTを扱う場合、通常はリソースの観点から考えることから始めるのが役立ちます。この場合、リソースは単に「銀行口座」ではなく、その銀行口座のトランザクションです...しかし、JSON-RPCは「メソッド」パラメーターを義務付けず、すべてエンドポイントの「パス」によってエンコードされます。
REST 預金 とPOST /Bank/Account/John/Transaction
JSON要求に{"jsonrpc": "2.0", "id": 12, "params": {"currency":"USD","amount":10}}
。
JSON応答は次のようになります{"jsonrpc": "2.0", "result": "sucess", "id": 12}
REST Withdraw with POST /Bank/Account/John/Transaction
...も同様です。
... GET /Bank/Account/John/Transaction/12345@13
...これは、その正確なトランザクションのJSONレコードを返す可能性があります(たとえば、ユーザーは通常、口座の借方と貸方のレコードを必要とします)。のようなもの{"jsonrpc": "2.0", "result": {"debits":[...],"credits":[...]}, "id": 13}
。(REST)GETリクエストに関する規則には、「@ id」によるIDのエンコードを含めることができるため、JSONを送信する必要はありませんが、応答パックでJSON-RPCを使用します。
リソースをリクエストする場合、RESTful APIは設計上優れています。単純なCRUD以外の多くのパラメーターと複雑なメソッドを使用して複雑なデータを要求する場合、RPCが適切な方法です。