Springの「GUIDES」を解読する旅　Consuming a RESTful Web Service編　つっこみ大歓迎！

#Consuming a RESTful Web Service

##RESTとは
[こちらの記事](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)が参考になります。

Consuming a RESTful Web Serviceでは
ブラウザでURIを入力すればリソース(WEBサービスに関わるデータ)を参照できるサービスのことである。

分散型システムで複数のソフトウェアに情報を共有させるときに便利な仕組みである。

##何をしたいか
springマニュアルのほうでランダムにマニュアル文章を返すAPIが用意されている。
 http://gturnquist-quoters.cfapps.io/api/random
今回のConsuming a RESTful Web ServiceはこのAPIからデータを取得するための機能である。

##引用文のクラスを作る(src/main/java/hello/Quote.java)

```java:src/main/java/hello/Quote.java
package hello;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {

    private String type;
    private Value value;

    public Quote() {
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Value getValue() {
        return value;
    }

    public void setValue(Value value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Quote{" +
                "type='" + type + '\'' +
                ", value=" + value +
                '}';
    }
}
```

###`@JsonIgnoreProperties`とは？

以下、マニュアルからの引用です。
>As you can see, this is a simple Java class with a handful of properties and matching getter methods. It’s annotated with @JsonIgnoreProperties from the Jackson JSON processing library to indicate that any properties not bound in this type should be ignored

`@JsonIgnoreProperties`はプロパティがJSON形式に当てはまらない場合に、それを無視するというアノテーションです。ということなのでこれを付けておくことで余計なデータを無視できます。今回接続するサービスはJSON形式というデータを返してきますのでそれに対応させる記述のようです。JSONで返されるプロパティと名前をそろえてなければなりません。

中身は単純なゲッターとセッターになっています。

###toString()メソッド
toString()メソッドはデフォルトでObjectの参照先を表す文字列を返してきますので、オーバーライドしてこれを変更しています。type(後述)と引用した文章であるvalueを返すようにしていますね。

##引用の内容クラス(src/main/java/hello/Value.java)を作る

```java:src/main/java/hello/Value.java
package hello;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {

    private Long id;
    private String quote;

    public Value() {
    }

    public Long getId() {
        return this.id;
    }

    public String getQuote() {
        return this.quote;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setQuote(String quote) {
        this.quote = quote;
    }

    @Override
    public String toString() {
        return "Value{" +
                "id=" + id +
                ", quote='" + quote + '\'' +
                '}';
    }
}
```

引用の中身をIDやQuoteに分類してクラスにしてありますね。
整理整頓のために行っているようです。
こちらはQuote.java内で使われます。

##実行用のクラス(Application.java)を作る

```java:src/main/java/hello/Application.java
package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.client.RestTemplate;

public class Application {

    private static final Logger log = LoggerFactory.getLogger(Application.class);

    public static void main(String args[]) {
        RestTemplate restTemplate = new RestTemplate();
        Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
        log.info(quote.toString());
    }

}
```

###ログを出力する
`private static final Logger log = LoggerFactory.getLogger(Application.class);`でログを取得、`log.info(quote.toString());`で出力してます。デフォルトではコンソールに出力されます。

###RestTemplateを使用してAPIからデータ取得する
`Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);`でアドレスを指定してJSONデータを取得していますね。

　getForObjectでは第二引数に先ほど作ったQuote.classを設定しています。これによりJSONデータをもとにQuoteクラスがNewされて?それがquoteの変数に格納されます。QuoteクラスのsetValue()もこのタイミングで自動で行われるのでしょうか？Value.javaもNewされてそれがQuoteのvalueとなっているようです。おそらくどちらのクラスにもつけられた`@JsonIgnoreProperties(ignoreUnknown = true)`がそこらへんを自動化させているのでしょうが、詳しいことは解釈できませんでした。裏での挙動が分かる方いらっしゃいましたらメッセージいただけるとありがたいです。

##Spring Bootを使用する

 ここまではSpring Bootを使用していないので次はSpring Bootを使用した場合のApplication.javaの記述方法です。Spring Bootを使うメリットは以下のように書かれています。

>One of the advantages is that we might want to let Spring Boot manage the message converters in the RestTemplate, so that customizations are easy to add declaratively.

Spring BootにRestTemplateにおけるmessage convertersの管理をさせることによって、宣言的にカスタマイズを加えることができるようになる。ということらしいです。

###Spring Boot用の実行クラスを作成する

```java:src/main/java/hello/Application.java
package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class Application {

	private static final Logger log = LoggerFactory.getLogger(Application.class);

	public static void main(String args[]) {
		SpringApplication.run(Application.class);
	}

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Bean
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			Quote quote = restTemplate.getForObject(
					"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
			log.info(quote.toString());
		};
	}
}
```

このコードに関する説明は以下の通り。

>The RestTemplateBuilder is injected by Spring, and if you use it to create a RestTemplate then you will benefit from all the autoconfiguration that happens in Spring Boot with message converters and request factories. We also extract the RestTemplate into a @Bean to make it easier to test (it can be mocked more easily that way).

こちらはまだ私の学習状態では解読不可です。RestTemplateBuilderは[こんな記事：Spring Boot 1.4+でRestTemplate(HTTPクライアント)を使う](https://qiita.com/kazuki43zoo/items/7cf3c8ca4f6f2283cefb)がありましたので参考までに。そもそもこの時点でautodonfigurationに関することやbeanに関することがでてきていないのに急にbeanなどの知識前提に説明されていることに無理がある。このマニュアル、ちゃんと体系づけたものにできないものか？beanの説明がのっている箇所を探したのですが該当箇所が見つからないです。書籍で読むしかないのでしょうか。