7

すべてのWebアプリケーション(すべてのWebサイト)はサービスです。(...)WebサイトをWebサーファーが使いやすくする機能により、WebサービスAPIもプログラマーが使いやすくなります。

リチャードソンとルビー、「RESTFulWebサービス」

私が意図しているように、WebサービスでもあるWebサイトは、ユーザーエージェントが何を要求するかに応じて、そのリソースの複数の表現を提供します。APIは、いわばWebサイト自体であり、個別に提供されるものではありません。

これは、世の中に出回っている多くの人気のある「RESTAPI」には当てはまりません。たとえば、TwitterのAPIはhttp://api.twitter.com/1/にあり、URIの「1」はAPI自体のバージョンです。Socialcastは、 https: //demo.socialcast.com/api/でREST APIも提供します。第3レベルの名前は、アドレス指定するネットワークの名前です。

これは私には間違っているようです。http://www.example.com/blogにブログがある場合、ロボット専用のJSONを提供するために、別の場所にAPIを提供する必要はありません。http://www.example.com/blog/posts/http://api.example.com/blog/postsの2つの異なるURIを使用する代わりに、前者だけを使用し、複数の表現を使用できるようにする必要があります。application/jsonユーザーに提供したいJSONAPIの場合。

例1:私のブログへの投稿を要求するブラウザ。

リクエスト:

curl -i \
 -H "Accept: text/html" \
 -X GET \
 http://www.example.org/blog/posts/

応答:

 200 OK
 Content-Type: text/html; charset=utf-8

 <html><body><h1>Posts</h1><ol><li><h2>My first post ...

例2:同じURIですが、今回はロボットがリクエストを行います。

リクエスト:

curl -i \
 -H "Accept: application/json" \
 -X GET \
 http://www.example.org/blog/posts/

応答:

 200 OK
 Content-Type: text/html; charset=utf-8

 {
    "posts": [
        {
            "id": 1,
            "title": "My first post" ...

APIのバージョン番号は、リクエストヘッダーの「Accept」フィールドにエンコードする必要があります。特に、TwitterのようにURIを強く入力することは避けてください(「statuses / show.json?id=210462857140252672」または「statuses/show / 210462857140252672.json ")。

統一されたアプローチを採用することで柔軟性を失う可能性がありますが(ただし、Cool URIは決して変更されるべきではありませんか?)、REST(または少なくとも私の解釈)を順守することでより多くのメリットが得られると思います。

APIとWebサイトを分離するか、それらを統合するか、どちらがより正しいアプローチですか?

4

4 に答える 4

8

ここには正しいことも悪いこともありません。API開発が特定のクライアント要件によって推進されている場合、RESTとRFCに厳密に従うことは難しい場合があります。

実際には、人間のユーザーはAPIクライアントと比較して異なる動作パターンを持っているため、異なる処理が必要です。最も明確な違いは、多くのAPIが非常にデータ集約的であり、バッチ操作とデータダンプ用に設計されているのに対し、人間のユーザー向けのアプリケーションはより「反応的」であり、多くの場合、段階的に、要求ごとに処理を行うという事実に由来します。その結果、多くのプロジェクトでAPIのURL設計が最適化され、複数のネットワークラウンドトリップや繰り返しのストレージ呼び出しでクライアントとサーバーのリソースが無駄になるのを防ぎます。

内部的には、API実装は、APIが提供する操作の種類に合わせて最適化された、コアアプリケーションとは異なる設計になっていることがよくあります。たとえば、API実装は別のキャッシュ戦略を使用する場合があります。ここで、コードを分割する場合は、API呼び出しのみを処理するホストのクラスターを作成することをお勧めします。ここで、APIを別のドメインに配置すると、負荷管理に役立ちます。別のドメインを使用すると、高負荷サイトでの負荷分散が簡単になります。対照的に、同じドメイン名で/ api URLプレフィックスを使用する場合(ただし、クラスターが分離している場合)、APIとWebフロントエンドクラスター間でリクエストフローを分割する作業を行うには、スマート(L7対応)ロードバランサーが必要です。しかし、そのようなロードバランサーはより高価です。

したがって、TwitterのようなものがAPIを分離する非常に優れた技術的理由があるかもしれませんが、他の実装への参照はあなたのプロジェクトに適用されないかもしれません。設計の初期段階にある場合は、同じドメインで統一されたURLスキームから始めたいと思うかもしれませんが、最終的には、アプローチを変更するための優れた実際のユースケースがあることに気付くかもしれません。リファクタリング。

PSここでバージョニングに関する長い議論があります-APIバージョニングのベストプラクティス?

PSS強く入力されたURLは、迅速なデバッグに役立ちます。.jsonを使用してブラウザにURLを入力するだけで、コマンドラインに切り替えることなく結果をすばやく取得できます。ただし、「accept」ヘッダーが推奨される方法であることに同意してください

API用のPSSSSEO?優れたURLデザインがどのように役立つかはわかりますが、検索エンジンの場合、サービスが同じパス/ドメイン名で複数の出力形式を提供している場合は、おそらく無関係です。結局のところ、検索エンジンは人間のユーザー向けに構築されており、人間のユーザーはXMLとJSONを消費しません。

于 2013-03-18T09:55:07.317 に答える
2

WebとRESTfulAPIは異なる方法で動作する可能性があります。

理論的には、リクエストhttp://mysite.com/blog/1はHTMLページを返す必要があるのか​​、データ(JSON、XML ...)だけを返す必要があるのか​​をどのように区別しますか?Accept httpヘッダーの使用に投票します:

Accept: text/html <-- Web browsers
Accept: application/json <-- Applications/Relying parties consuming data or performing actions

Twitter、Facebook、またはその他のサイトがWebブラウザーと依存関係者の両方を混在させないのはなぜですか?正直なところ、それは恣意的な決定だと私は主張します。

おそらく私は1つの考えられる理由を提供することができます:Webブラウザ/検索エンジンロボットのURLはフレンドリーである必要があります-これらはSEOでよりよく機能するためURLです。そのため、SEO対応のURLは、RESTに関してはあまり意味的ではないかもしれませんが、検索エンジンや人間のユーザー向けです。

最後に:どちらが良いですか(それは私の意見です)?

  • SEOが必要な場合は、別のURLを使用してください。
  • SEOは必要ありませんその後、同じドメインと形式でURLを統合します
于 2013-03-12T12:01:26.227 に答える
1

この決定は、SEO や URL がいかに「フレンドリー」であるかに関係があるべきであるという他の回答には同意しません (ロボットも [作成された] 人です!)。しかし、私の直感では、URI を統一することでより良い SEO の結果が得られることがわかります。これは、API URI がワールド ワイルド Web からリンクされる (可能性は低い) イベントでのページランクも統一されるためです。

この決定、サーバーとクライアントの能力に基づいて行われます。それらが Accept 要求ヘッダーを設定でき、サーバーが透過的なコンテンツ ネゴシエーションを行うのに十分なほどスマートである場合は、必ず URI を統一してください。これが私がしていることです (私の唯一の JSON クライアントは私自身ですが、Accept ヘッダーを制御する Web アプリの他の HTML 部分から提供される AJAX 要求を発行します)。

json 応答を取得したい Web ユーザーなど、クライアントが要求ヘッダーを設定できない場合、デフォルト (おそらく text/html) で終了します。このため、固有の URI (/foo.txt、/foo.rtf) で発生するネゴシエートされていない応答を許可したい場合があります。従来、これは、あたかもファイル名拡張子であるかのように、形式をドットで区切られた URI に追加することによって行われます (ただし、通常はそうではなく、mod_rewrite がジャグリングを行います)。これにより、ファイル名拡張子を必要とするプラットフォーム上の古いクライアントがファイルを保存できるようになります。意味のあるもので。

私のサイトのほとんどのページは次のように機能します。

  1. リクエストURLからSQLクエリを判別。(例/cars?colour=black=> SELECT * FROM cars WHERE colour='black')
  2. SQL クエリを発行します。
  3. このファイルでサポートされているリストから、受け入れ可能な応答タイプを決定します。これは通常 HTML と HAL (すなわち JSON) ですが、時には XML も含まれます。text/html他に許容できるものがない場合にフォールバックします。
  4. if(HTML) 吐き出して<HEAD>(<NAV>パラメータを考えると: <h1>Black Cars</h1>)
  5. 最も受け入れられる応答タイプを使用して結果を吐き出します。
    この関数は、SQL 結果オブジェクトを受け取り、それを HTTPLinkヘッダー、HTML<LINK>要素のストリーム、HAL の_linksキー、XLink 要素のストリーム、HTML<TABLE>要素 (要素を含むセルを含む<A>)、または CSV ファイルに変換する方法を知っています。SQL クエリは 0 行を返す場合があります。その場合、その出力が使用されていた場合、HTML テーブルの代わりにユーザー フレンドリなメッセージが書き込まれます。
  6. if(HTML) 吐き出す<FOOTER>

この基本的な概要は、私の Web アプリで約 30 の異なるリソース コレクションを処理しますが、それぞれに要求 URI が呼び出すオプションのセットが異なるため、パラメーターの検証に関してそれぞれの開始が異なります。

ここまで説明してきましたが、各リソースのすべての詳細を 1 か所で処理し、形式 X または形式 Y での出力のジェネリックを共通のライブラリ関数で処理すると便利であることがわかります。これは、私の人生を楽にし、Don't Repeat Yourself の格言を順守するのに役立つ実装の詳細です。

于 2013-03-12T13:24:16.347 に答える
0

私は間違いなく web-site == web-service アプローチに同意しません。

簡単に言えば、Web サイトは、Web サービスを消費し、Web で使用するために適切な形式でデータをレンダリングするクライアント、つまり単なるクライアントとして扱われるべきです。モバイル アプリケーションがクライアントであるのと同じように、同じ Web サービスを使用し、モバイルでの使用に適した形式でデータをレンダリングします。

Web サービスはサービス プロバイダーです。他のすべては単なるクライアントです。Web サイト、Android アプリ、iPhone アプリなど。

于 2013-03-19T12:28:23.017 に答える