SpringでHATEOASなREST APIアプリケーションを作った

Spring HATEOASを使います。

ソースコード全体は↓

https://github.com/bond-kaneko/TrySpringHATEOAS

HATEOASとは

この資料 を参考にして簡単に紹介します。

HATEOASはRESTの拡張版です。ブログAPIを例として、RESTとHATEOASの違いを説明します。例えばブログの詳細をリクエストしたとします。

RESTではリソースをレスポンスとして返すので、この場合は

  • ブログID

  • ブログタイトル

  • 著者名

  • 更新日時

のような値が返ってきます。

HATEOASの場合は、RESTのレスポンスに加えて、そのブログ(リソース)に対して行える操作も返します。 例えば

  • ブログ編集

  • ブログ削除

などです。各操作を行うためのURLの形式をとっている場合が多いです。

HATEOASでは、バックエンドでどのような操作を行えるかを、フロントエンドが知っている必要がないため、フロントエンドとバックエンドをより分離できるのがメリットです。

作ったもの

/greeting?name=Worldへリクエストを送ると、↓のようなレスポンスを返すアプリケーションです。

{
  "content":"Hello, World!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=World"
    }
  }
}

_links以下がリソースに対して行える操作です。今回は単に、同じリクエストを再度行うためのURLを返すようにしています。

レスポンスの作成

レスポンスへ操作を追加する際は、↓のようにしています。

greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel());

methodOn(GreetingController.class).greeting(name)が今回リクエストを受け取ったメソッドを表していて、それをlinkTo()の引数に渡してやればURLへ変換されます。

greeting.add()を使えるのは、Greeting.javaがSpring HATEOASのRepresentationModelを継承しているためです。

public class Greeting extends RepresentationModel<Greeting> {
    private final String content;

    @JsonCreator
    public Greeting(@JsonProperty("content")String content) {
        this.content = content;
    }
    ...

Jacksonがjavaクラスからjsonへの変換を行う際に、@JsonCreatorが付いたメソッドを使用します。@JsonPropertyで指定されたプロパティ名を元にjsonへの変換が行われます。

動作検証


↓のようなレスポンスが返ってきており、意図した通りに動作しているのが分かります。

% curl http://localhost:8080/greeting                               
{
  "content":"Hello, World!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=World"
  }
}

参考文献

https://spring.io/guides/gs/rest-hateoas/

https://www.slideshare.net/josdirksen/rest-from-get-to-hateoas