18

HATEOAS の背後にある中心的なアイデアの 1 つは、クライアントが単一のエントリ ポイント URL から開始し、公開されているすべてのリソースとそれらに利用可能な状態遷移を検出できるようにすることです。それが HTML でどのように機能するか、ブラウザの背後で人間がリンクをクリックして「送信」ボタンをクリックする様子は完全に理解できますが、この原則をどのように適用すれば (運が悪いか) 対処できなかった問題に適用できるか疑問に思っています。

私は、RESTful な設計原則が論文や教育記事で提示されているのが好きです。それはすべて理にかなっています。コーヒーを GET する方法はその良い例です。慣習に従い、単純で退屈な詳細のない例を考えてみます。郵便番号と都市を見てみましょう。

問題1

郵便番号で都市を検索するための RESTful API を設計したいとしましょう。郵便番号にネストされた「都市」と呼ばれるリソースを思いついたので、GET onhttp://api.addressbook.com/zip_codes/02125/citiesは、たとえばドーチェスターとボストンを表す 2 つのレコードを含むドキュメントを返します。

私の質問は、HATEOAS を通じてそのような URL をどのように発見できるのでしょうか? で最大 40K のすべての郵便番号のインデックスを公開することはおそらく非現実的http://api.addressbook.com/zip_codesです。40K のアイテム インデックスを使用することは問題ではありませんが、この例は私が作成したものであり、はるかに大きな規模のコレクションが存在することを思い出してください。

したがって、基本的には、リンクではなくリンク テンプレートを公開したいと思います。これhttp://api.addressbook.com/zip_codes/{:zip_code}/citiesは、原則に反し、クライアントが所有する帯域外の知識に依存します。

問題 2

特定のフィルタリング機能を備えた都市インデックスを公開したいとしましょう。

  • GET onhttp://api.addressbook.com/cities?name=Xは、名前が一致する都市のみを返しXます。

  • GET onhttp://api.addressbook.com/cities?min_population=Yは、人口が以上の都市のみを返しYます。

もちろん、これら 2 つのフィルターは一緒に使用できますhttp://api.addressbook.com/cities?name=X&min_population=Y

ここでは、URL だけでなく、これら 2 つの可能なクエリ オプションと、それらを組み合わせることができるという事実も公開したいと思います。これは、これらのフィルターのセマンティクスとそれらを動的 URL に結合する背後にある原則についてのクライアントの帯域外知識がなければ、まったく不可能のようです。

では、HATEOAS の背後にある原則は、このような些細な API を本当に RESTful にするのにどのように役立つのでしょうか?

4

5 に答える 5

4

XHTML フォームを使用することをお勧めします。

GET /

HTTP/1.1 OK

<form method="get" action="/zip_code_search" rel="http://api.addressbook.com/rels/zip_code_search">
   <p>Zip code search</p>
   <input name="zip_code"/>
</form>

GET /zip_code_search?zip_code=02125

HTTP/1.1 303 See Other
Location: /zip_code/02125

HTML に欠けているのは、 のrel属性ですform

この記事をチェックしてください:

要約すると、RESTful サービスのデフォルト表現として XHTML を検討する理由はいくつかあります。まず、独自の要素を発明する代わりに<a><form>、 、 などの重要な要素の構文とセマンティクスを活用できます。<input>第 2 に、サービスはユーザーとアプリケーションの両方から参照できるため、サイトのように感じられるサービスになります。XHTML は依然として人間によって解釈されます。実行時のユーザーではなく、開発中の単なるプログラマーです。これにより、開発プロセス全体が簡素化され、消費者がサービスの仕組みを簡単に理解できるようになります。最後に、標準の Web 開発フレームワークを利用して RESTful サービスを構築できます。

OpenSearchもチェックしてください。


リクエストの数を減らすには、次のレスポンスを検討してください。

HTTP/1.1 200 OK
Content-Location: /zip_code/02125

<html>
<head>
<link href="/zip_code/02125/cities" rel="related http://api.addressbook.com/rels/zip_code/cities"/>
</head>
...
</html>
于 2012-02-01T19:48:53.237 に答える
2

質問 1 への回答として、単一のエントリ ポイントがhttp://api.addressbook.com/zip_codesであると想定しています。その意図は、クライアントが郵便番号のコレクション全体を走査し、最終的にそれらに関連する都市を取得できるようにすることです。

その場合、http://api.addressbook.com/zip_codesリソースが郵便番号の最初のページへのリダイレクトを返すようにします。次に例を示します。

http://api.addressbook.com/zip_codes?start=0&end=xxxx

これには、「ページ」分の郵便番号リンク (システムが処理するのに適した番号と、次のページ (および前のページがある場合は前のページ) へのリンク) が含まれます。

これにより、クライアントは必要に応じて郵便番号のリスト全体をクロールできます。

各ページで返される URL は次のようになります。

http://api.addressbook.com/zip_codes/02125

次に、必要に応じて、郵便番号の URL によって返される表現に都市情報を含めるか、それへのリンクを含めるかを決定する必要があります。

これで、クライアントは、郵便番号のリスト全体を走査してから、それぞれの郵便番号 (次に都市) を要求するか、郵便番号のページを要求してから、部分へのドリルダウンを要求するかを選択できます。

于 2012-04-17T22:30:44.910 に答える
2

この解決策が思い浮かびますが、実際にお勧めできるかどうかはわかりません。リソース URL を返す代わりに、エンドポイントを説明する WADL URL を返します。例:

<application xmlns="http://wadl.dev.java.net/2009/02" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <grammars/>
  <resources base="http://localhost:8080/cities">
    <resource path="/">
      <method name="GET">
        <request>
          <param name="name" style="query" type="xs:string"/>
          <param name="min-population" style="query" type="xs:int"/>
        </request>
        <response>
          <representation mediaType="application/octet-stream"/>
        </response>
      </method>
    </resource>
  </resources>
</application>

この例は、次の Java コードから CXF によって自動生成されました。

import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

public class Cities {
    @GET
    public Response get(@QueryParam("name") String name, @QueryParam("min-population") int min_poulation) {
        // TODO: build the real response
        return Response.ok().build();
    }
}
于 2012-02-01T19:03:40.460 に答える
1

私はこれらの同じ質問に遭遇していました-それで私はこれらの問題の両方を解決する実際的な例を試しました(そしてあなたがまだ考えていないいくつかの問題)。http://thereisnorightway.blogspot.com/2012/05/api-example-using-rest.html?m=1

基本的に、問題1の解決策は、表現を変更することです(Royが言うように、リソースに時間を費やします)。すべてのzipを返す必要はありません。リソースにページングを含めるだけです。たとえば、ニュースサイトからニュースページをリクエストすると、すべての記事が同じURL構造である場合でも、今日のニュースとその他のニュースへのリンクが表示されます。つまり、... article/123などです。

問題2は少し厄介です-基本的にURLの機能を反映するために例で使用したOPTIONSと呼ばれる少し使用されたコマンドがhttpにあります-これは表現でも解決できますが、もっと複雑になります。基本的に、リソースの機能(オプションのパラメーターを含む)を示すカスタム構造を返します。

どう考えているか教えてください!

于 2012-06-12T04:34:59.523 に答える
0

ブックマークの URL をスキップしたようです。これは最初の URL であり、都市や郵便番号を取得する URL ではありません。

したがって、ab:=http://api.addressbook.com から開始します。

この最初のリンクは、使用可能なリンクのリストを返します。これがウェブの仕組みです。www.yahoo.com にアクセスすると、どこに行くのかわからないままリンクをクリックし始めます。

したがって、元のリンク ab から: 他のリンクを取得し、それらのリソースにアクセスする方法や送信できるパラメーターを説明する REL リンクを含めることができます。

システムを設計する際に最初に考えたことは、ブックマーク ページから始めて、アクセスできるさまざまなリンクをすべて決定することでした。

HTMLのような先入観のある仕様がない限り、マシンがそこにあるものに適応できるということを私が買うのは難しいです。クライアントは、すべての可能性を知っている開発者によって構築され、それらのリンクが利用可能であることを「潜在的に」期待するようにアプリケーションをコーディングする可能性が高くなります。リンクが利用可能な場合、プログラムは、リソースを実行する前に開発者が実装したロジックを使用できます。そこにない場合は、リンクを実行しません。最後に、アプリケーションのトラバースを開始する前に、可能なパスがレイアウトされます。

于 2012-02-01T21:41:15.983 に答える