Edited at

Spring JPA Data with REST と Lombokで恐ろしく簡単にREST APIを作成する。

More than 1 year has passed since last update.


昨今のWebアプリケーションといえばREST

昨今、Webアプリケーションといえば、HTML+JavaScriptによるクライアント層ブラウザ上で動作し、サーバはREST APIでデータを配信するアーキテクチャを取ります。

本記事ではサーバのREST APIをJavaで恐ろしく簡単に作れるぞ、ということをご紹介します。


Spring Boot + Lombok

Spring Boot を使うと、簡単にWebアプリケーションを作成することができます。

また、Lombokを使うと、冗長なコードをJavaから排除することができます。

今回は、この2つを組み合わせることで、恐ろしく簡単にREST APIを作成します。

サンプルとして、TODOをRESTできるAPIを作成します。


手順


  1. SPRING INITIALIZR でアプリケーションのベースを作成する。

    image.png

    Selected Dependenciesには、

    JPA, H2, Lombok, Rest Repositories

    を指定します。

    Generate Projectを押すとzipファイルがダウンロードできるので、解凍します。


  2. データ定義とアプリケーションの作成

    データ構造をJavaのクラスとして作成します。


package com.ukiuni.easyrest.entity;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import lombok.Data;

@Data
@Entity
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

private String title;
private String description;
private boolean done;
@Temporal(TemporalType.TIMESTAMP)
private Date deadline;
}

キモはクラスに付いているアノテーションの@Dataです。Lombokが定義するアノテーションで、アクセサメソッドを自動的に付与してくれます。これによりプログラマは冗長なgetter/setterを記述することなく、フィールドによるデータ定義に集中することができます。

このデータ構造をそのままREST APIのCRUDの型構造にするためのクラスを定義します。

package com.ukiuni.easyrest.repository;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import com.ukiuni.easyrest.entity.Todo;

@RepositoryRestResource(collectionResourceRel = "todos", path = "todos")
public interface TodoRepository extends PagingAndSortingRepository<Todo, Long> {
}

インターフェースを定義するのみです。中身の実装は不要です。

以上でソースコードの記述は終わりです。簡単。


起動と操作

起動します。アプリケーションのディレクトリで

gradle bootRun

で起動します。

操作してみましょう。

curlコマンドを使用します。

$ curl -i http://localhost:8080/todos

HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 16 Nov 2017 11:47:24 GMT

{
"_embedded" : {
"todos" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/todos"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}

"todos": [ ] と、空データが取得できているのがわかります。

さて、Todoを一件作成してみます。curlコマンドを利用します。

$ curl -i -X POST -H "Content-Type:application/json" -d "{  \"title\" : \"アドベントカレンダー\",  \"description\" : \"記事書かなきゃ。\", \"deadline\":\"2017-12-21T07:00:00.000Z\" }" http://localhost:8080/todos

{
"title" : "アドベントカレンダー",
"description" : "記事書かなきゃ。",
"done" : false,
"deadline" : "2017-12-21T07:00:00.000+0000",
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos/1"
},
"todo" : {
"href" : "http://localhost:8080/todos/1"
}
}
}

1番が作成されたようです。確認してみます。

$ curl -i http://localhost:8080/todos

HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 16 Nov 2017 11:50:57 GMT

{
"_embedded" : {
"todos" : [ {
"title" : "アドベントカレンダー",
"description" : "記事書かなきゃ。",
"done" : false,
"deadline" : "2017-12-21T07:00:00.000+0000",
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos/1"
},
"todo" : {
"href" : "http://localhost:8080/todos/1"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/todos"
}
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}

作成したものが取得できてますね。

PUTでUPDATEしてみます。

$curl -i -X PUT -H "Content-Type:application/json" -d "{  \"title\" : \"アドベントカレンダー\",  \"description\" : \"記事書かなきゃ。頑張ろう。\", \"deadline\":\"2017-12-21T07:00:00.000Z\" }" http://localhost:8080/todos/1

HTTP/1.1 200
Location: http://localhost:8080/todos/1
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 16 Nov 2017 11:43:30 GMT

{
"title" : "アドベントカレンダー",
"description" : "記事書かなきゃ。頑張ろう。",
"done" : false,
"deadline" : "2017-12-21T07:00:00.000+0000",
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos/1"
},
"todo" : {
"href" : "http://localhost:8080/todos/1"
}
}
}

確認してみます。

$ curl -i http://localhost:8080/todos

HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 16 Nov 2017 11:51:55 GMT

{
"_embedded" : {
"todos" : [ {
"title" : "アドベントカレンダー",
"description" : "記事書かなきゃ。頑張ろう。",
"done" : false,
"deadline" : "2017-12-21T07:00:00.000+0000",
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos/1"
},
"todo" : {
"href" : "http://localhost:8080/todos/1"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/todos"
}
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}

アップデートされてますね。

最後、Deleteします。

$ curl -i -X DELETE http://localhost:8080/todos/1

HTTP/1.1 204
Date: Thu, 16 Nov 2017 11:45:45 GMT

消えたことを確認します。

$ curl -i http://localhost:8080/todos

HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 16 Nov 2017 11:47:24 GMT

{
"_embedded" : {
"todos" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/todos{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/todos"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}

"todos" : [ ] 消えてますね。


どうです?恐ろしく簡単でしょう?

データ構造と公開するためのRepositoryクラスを作成するだけでREST APIを作成することができました。

Javaの型定義の強さとアノテーション機能を使うことでこんなに簡単にREST APIを作成することができます。

どうですか?最近毛嫌いされがちなJavaですが、見直しました?

みなさんもエレガントにJavaを使いこなしてください。

サンプルコードはこちらにおいておきます。

現場からは以上です。