今回はBuilding a Hypermedia-Driven RESTful Web Serviceをやってみようと思う。
Hypermediaってどういうことやろうかと思っていたんだけれども、どうもJSONで色々返すことのようだ。
hypermedia-driven RESTは、Spring HATEOASというライブラリを使うらしい。これを使うとSpring MVCのコントローラーとリソースを簡単に設定できる(?)ようである。
まずはbuild.gradleを編集する
dependencies {
// compile("org.springframework.boot:spring-boot-starter-web:1.2.2.RELEASE")
// compile("org.springframework.boot:spring-boot-starter-actuator:1.2.2.RELEASE")
compile("org.springframework.boot:spring-boot-starter-thymeleaf:1.2.2.RELEASE")
// compile("org.springframework.boot:spring-boot-starter-security:1.2.2.RELEASE")
compile("org.springframework.boot:spring-boot-starter-data-rest:1.2.2.RELEASE")
compile("org.springframework.boot:spring-boot-starter-data-jpa:1.2.2.RELEASE")
compile("com.h2database:h2:1.4.183")
compile("org.webjars:jquery:2.1.3")
testCompile("org.springframework.boot:spring-boot-starter-test:1.2.2.RELEASE")
compile("com.fasterxml.jackson.core:jackson-databind")
compile("org.springframework.hateoas:spring-hateoas")
compile("org.springframework.plugin:spring-plugin-core:1.1.0.RELEASE")
compile("com.jayway.jsonpath:json-path:0.9.1")
}
gradle buildDependentsを実行しておく。
リソースにアクセスするためのクラスを作成
ここでは/greetingにアクセスしたらJSONを返すクラスを作るようなのだが、Greetingクラスを作ると前に作ったものとバッティングしそうなので、違うクラスを作成してみる。
ResourceSupportクラスを継承したら、Spring HATEOASに則ったモデルクラスが作れるらしい(適当に読んでいるので違う気もする)。あとはシンプルなPOJOを作るだけ。コンストラクタで代入とgetterを作ってねーと書いてある。
ちなみに私は未だにPOJOってのがなんなのかわかっていないのでついでに調べてみる。
シンプルなJavaのオブジェクトのことを指すらしい…。なんだろう、通常のクラスが色々脚色されすぎたせいで、普通のクラスが普通という感じがしなくなったからプレーンなやつのことをわざわざPOJOと呼ぶのか。
で、サンプルコードを参考に作ったのが以下のコードとなる。
package sample;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.hateoas.ResourceSupport;
public class Happy extends ResourceSupport {
private final String content;
@JsonCreator
public Happy(@JsonProperty("content") String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
アノテーションが付いてるんだけれども、これもPOJOなんか?どこからがPOJOでどこからばPOJOでないのかがわからない。@JsonCreaterと@JsonPropertyがあると、Jacksonでインスタンスを生成するときに捗る、みたいに書いてある。こうしておくとJacksonがHappyクラスを自動でJSONにしてくれるらしい。
モデルはできたので次はコントローラーを作ってみよう。
HappyControllerを作ってみる
あとはHappyモデルを返すHappyControllerを作ってみる。
HappyControllerは@Controllerアノテーションを使うことと、@RequestMappingアノテーション、@ResponseBodyアノテーションを使う。
package sample;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
@Controller
public class HappyController {
private static final String TEMPLATE = "Hello, %s";
@RequestMapping("/happy")
@ResponseBody
public HttpEntity<Happy> happy(
@RequestParam(value = "name", required = false, defaultValue = "Happy") String name
) {
Happy happy = new Happy(String.format(TEMPLATE, name));
happy.add(linkTo(methodOn(HappyController.class).happy(name)).withSelfRel());
return new ResponseEntity<Happy>(happy, HttpStatus.OK);
}
}
linkToメソッド、methodOnメソッド、withSelfRelメソッドなどが、ここの面白いところ(らしい)。HappyモデルはResourceSupportを継承しているので、addメソッドでlinkを追加できる。引数として、Linkクラスのインスタンスが必要なのだが、それをControllerLinkBuilderのメソッドで作っているらしい。
アプリケーションを起動する
ここまできたらあとは起動するだけ。いつものやつを打つ。
gradle bootRun
これで、http://localhost:8080/happy にアクセスしたら、JSONを返してくれる。
うーん、できたはできたのだが、Javaはアノテーションを使いまくる感じがするのだが、アノテーションってそんなにみんな覚えていられるものなのだろうか?いまいちお手軽さを感じられないのだが…。慣れのような気はするけれど、なんとなくモヤモヤする。
