RESTAPIの発見可能性とHATEOAS

RESTトップ

Spring5とSpringBoot2の基礎に焦点を当てた新しいLearnSpringコースを発表しました。

>>コースをチェックしてください

1。概要

この記事では、REST APIの発見可能性、HATEOAS、およびテストによって駆動される実際のシナリオに焦点を当てます。

2.APIを検出可能にする理由

APIの発見可能性は、十分な注目を集めていないトピックです。結果として、それを正しく行うAPIはほとんどありません。また、正しく実行されれば、APIをRESTfulで使いやすくするだけでなく、エレガントにすることもできます。

検出可能性を理解するには、アプリケーション状態のエンジンとしてのハイパーメディア(HATEOAS)の制約を理解する必要があります。REST APIのこの制約は、アプリケーション状態の唯一のドライバーとして、ハイパーメディア(実際にはハイパーテキスト)からのリソースに対するアクション/遷移の完全な検出可能性に関するものです。

インタラクションが会話自体を介して、具体的にはハイパーテキストを介してAPIによって駆動される場合、ドキュメントはありません。それは、実際にはAPIのコンテキスト外にある仮定を行うようにクライアントを強制します。

結論として、サーバーは、ハイパーテキストのみを介してAPIを使用する方法をクライアントに指示するのに十分な説明が必要です。HTTP会話の場合、Linkヘッダーを介してこれを実現できます。

3.発見可能性シナリオ(テストによる)

では、RESTサービスが検出可能であるとはどういう意味ですか?

このセクション全体を通して、Junit、安心、Hamcrestを使用して、発見可能性の個々の特性をテストします。RESTサービスは以前に保護されているため、各テストはAPIを使用する前に最初に認証する必要があります。

3.1。有効なHTTPメソッドを見つける

RESTサービスが無効なHTTPメソッドで消費された場合、応答は405 METHOD NOTALLOWEDである必要があります。

APIは、クライアントがその特定のリソースに許可されている有効なHTTPメソッドを検出するのにも役立ちます。このために、我々は使用することができます許可応答にHTTPヘッダーを:

@Test public void whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions(){ // Given String uriOfExistingResource = restTemplate.createResource(); // When Response res = givenAuth().post(uriOfExistingResource); // Then String allowHeader = res.getHeader(HttpHeaders.ALLOW); assertThat( allowHeader, AnyOf.anyOf( containsString("GET"), containsString("PUT"), containsString("DELETE") ) ); }

3.2。新しく作成されたリソースのURIを検出する

新しいリソースを作成する操作では、常に新しく作成されたリソースのURIを応答に含める必要があります。このために、LocationHTTPヘッダーを使用できます。

これで、クライアントがそのURIでGETを実行すると、リソースが使用可能になります。

@Test public void whenResourceIsCreated_thenUriOfTheNewlyCreatedResourceIsDiscoverable() { // When Foo newResource = new Foo(randomAlphabetic(6)); Response createResp = givenAuth().contentType("application/json") .body(unpersistedResource).post(getFooURL()); String uriOfNewResource= createResp.getHeader(HttpHeaders.LOCATION); // Then Response response = givenAuth().header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .get(uriOfNewResource); Foo resourceFromServer = response.body().as(Foo.class); assertThat(newResource, equalTo(resourceFromServer)); }

テストは単純なシナリオに従います。新しいFooリソースを作成し、HTTP応答を使用して、リソースが現在利用可能なURIを検出します。次に、そのURIに対してGETを実行してリソースを取得し、元のURIと比較します。これは、正しく保存されたことを確認するためです。

3.3。そのタイプのすべてのリソースを取得するためのURIを見つけます

特定のFooリソースを取得すると、次に何ができるかを見つけることができるはずです。利用可能なすべてのFooリソースを一覧表示できます。したがって、リソースを取得する操作では、その応答に、そのタイプのすべてのリソースを取得するURIを常に含める必要があります。

このために、Linkヘッダーを再び利用できます。

@Test public void whenResourceIsRetrieved_thenUriToGetAllResourcesIsDiscoverable() { // Given String uriOfExistingResource = createAsUri(); // When Response getResponse = givenAuth().get(uriOfExistingResource); // Then String uriToAllResources = HTTPLinkHeaderUtil .extractURIByRel(getResponse.getHeader("Link"), "collection"); Response getAllResponse = givenAuth().get(uriToAllResources); assertThat(getAllResponse.getStatusCode(), is(200)); }

rel関係によるURIの抽出を担当するextractURIByRelの完全な低レベルコードがここに示されていることに注意してください。

このテストは、RESTのリンク関係の厄介な問題をカバーしています。すべてのリソースを取得するURIは、rel =” collection”セマンティクスを使用します。

このタイプのリンク関係はまだ標準化されていませんが、すでにいくつかのmicroformatsで使用されており、標準化が提案されています。非標準のリンク関係を使用すると、RESTfulWebサービスのマイクロフォーマットとより豊富なセマンティクスに関する議論が始まります。

4.その他の潜在的な検出可能なURIとマイクロフォーマット

他のURIは、Linkヘッダーを介して検出される可能性がありますが、トピックとなるカスタムリンクリレーション、Atom Publishing Protocol、またはmicroformatsの定義など、より豊富なセマンティックマークアップに移行せずに、既存のタイプのリンクリレーションで許可されるものは限られています。別の記事の。

たとえば、クライアントは、特定のリソースでGETを実行するときに、URIを検出して新しいリソースを作成できる必要があります。残念ながら、モデル作成セマンティクスとのリンク関係はありません。

幸い、作成用のURIは、そのタイプのすべてのリソースを取得するためのURIと同じであることが標準的な方法ですが、唯一の違いはPOSTHTTPメソッドです。

5。結論

私たちは見てきたREST APIはルートからと事前の知識と完全に検出可能であるか-クライアントは、ルート上のGETを行うことによって、それをナビゲートすることができます意味します。今後、すべての状態変更は、REST APIが表現で提供する利用可能で検出可能な遷移を使用してクライアントによって駆動されます(したがって、Representational State Transfer)。

この記事では、REST Webサービスのコンテキストでの検出可能性のいくつかの特性について説明し、HTTPメソッドの検出、作成と取得の関係、すべてのリソースを取得するためのURIの検出などについて説明しました。

これらすべての例とコードスニペットの実装は、GitHubで入手できます。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。

RESTボトム

Spring5とSpringBoot2の基礎に焦点を当てた新しいLearnSpringコースを発表しました。

>>コースをチェックしてください