はじめに
Spring Data RESTを使って、MySQLにアクセスする最も簡単なREST APIを作成します。
参考
Accessing JPA Data with REST
https://spring.io/guides/gs/accessing-data-rest/
前提条件
下の記事の後の状態を前提にしています
Spring BootとAngularUI UI-Routerを使ってみる
MySQLを利用できること
環境
JVM: 1.8.0_45 (Oracle Corporation 25.45-b02)
OS: Mac OS X 10.11.3 x86_64
MySQL: Server version: 5.5.28 Source distribution
Spring Tool Suite
Version: 3.7.3.RELEASE
Build Id: 201602250940
Platform: Eclipse Mars.2 (4.5.2)
(こちらから入れました https://spring.io/tools/sts/all)
Buildship: Eclipse Plug-ins for Gradle 1.0.13.v20160411-1723
(Help -> Eclipse marketplaceから入れました)
手順
依存するLibraryを追加する
Spring Data JPA、Spring Data REST、MySQL Connector/Jを使えるように、ビルドスクリプトの依存物として、// Addを追記します。
dependencies {
compile 'org.webjars:jquery:2.2.3'
compile 'org.webjars:angularjs:1.5.3'
compile 'org.webjars:angular-ui-router:0.2.18'
compile 'org.webjars:bootstrap:3.3.6'
// Add
compile('org.springframework.boot:spring-boot-starter-data-jpa')
// Add
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
// Add
compile('mysql:mysql-connector-java')
}
追記を反映するために、Package ExplorerでSSP37(プロジェクトルート)を選び右クリック、
Gradle -> Refresh Gradle Project
をクリックします。
Package ExplorerのProject and External Dependenciesに、追記したJarあるか確認します。
参考
Spring IO Platform Reference Guide
Appendix A. Dependency versions
http://docs.spring.io/platform/docs/2.0.3.RELEASE/reference/htmlsingle/#appendix
WebJars http://www.webjars.org/
設定する
JPAやMySQLを使うのに、必要最小限と思われる設定をします。
spring.data.rest.basePath=/api
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database=MYSQL
spring.jpa.hibernate.ddl-auto=update
spring.data.rest.basePath
REST APIのルートの設定です。変えたほうが分かり易いと思い変えました。
参考
Spring Data REST - Reference Documentation
4.6.1. Changing the base URI
http://docs.spring.io/spring-data/rest/docs/2.4.4.RELEASE/reference/html/#getting-started.basic-settings
spring.datasource.*
MySQLへの接続文字列です。ご自分の環境に合わせて値を指定して下さい。
hibernateが自動で、テーブルの作成や項目の変更、破棄をしてくれたりするので、それらが行える権限を持つ、MySQLのユーザーを指定して下さい。
参考
Spring Boot Reference Guide
29.1.2 Connection to a production database
https://docs.spring.io/spring-boot/docs/1.3.3.RELEASE/reference/htmlsingle/#boot-features-connect-to-production-database
spring.jpa.database=MYSQL
自動で生成されるSQLやDDLが、MySQL向けになるように指示します。
spring.jpa.hibernate.ddl-auto=update
Entityになるクラスを作ると、自動でテーブルの作成、項目変更をしてくれるようにします。
参考
Spring Boot Reference Guide
73.5 Configure JPA properties
https://docs.spring.io/spring-boot/docs/1.3.3.RELEASE/reference/htmlsingle/#howto-configure-jpa-properties
Hibernate Reference Documentation
3.4. Optional configuration properties
Table 3.7. Miscellaneous Properties
hibernate.hbm2ddl.auto
Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
e.g. validate | update | create | create-drop
Entityを作る
簡単なEntityを作ってみます。
綴り(spelling)と好みか(favorite)を項目に持つ、単語(word)というEntityを作ってみました。
package com.example.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Word {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String spelling;
@Column(nullable = false)
private Boolean favorite;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSpelling() {
return spelling;
}
public void setSpelling(String spelling) {
this.spelling = spelling;
}
public Boolean getFavorite() {
return favorite;
}
public void setFavorite(Boolean favorite) {
this.favorite = favorite;
}
}
Repositoryを作る
先ほどのWordを操作するRepositoryを作ります。
Spring Data RESTは、このようなRepositoryを作ると、そのEntityをCRUD操作できるAPIを自動で公開してくれます。
package com.example.domain;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
public interface WordRepository extends PagingAndSortingRepository<Word, Long> {
List<Word> findBySpellingLikeOrderBySpellingAsc(@Param("spelling") String spelling);
}
APIを使ってみる
それではcURLで、APIを使ってみましょう。
まずはWebアプリケーションを起動します。
Spring Data RESTが公開するAPIのPathは、設定したAPIのルートと、Repositoryを作ったEntityの名前を小文字にして、複数形のsを付け、連結したものになります。
今回は、APIのルートを/apiに設定し、EntityのWordはwordsになるので、Path名は/api/wordsとなります。
そのPathにcurlでアクセスします。
$ curl http://localhost:8080/api/words
下のような応答がありました。
{
"_embedded" : {
"words" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words"
},
"profile" : {
"href" : "http://localhost:8080/api/profile/words"
},
"search" : {
"href" : "http://localhost:8080/api/words/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
とりあえずレコードを一件登録してみます。
-dで指定するJSON部分に、idを除くEntityの全ての項目を指定し、先ほどのPathへPOSTすると登録できます。
$ curl -X POST -H "Content-Type:application/json" -d '{ "spelling": "APPLE", "favorite": true }' http://localhost:8080/api/words
id=13で登録できたようです。13は環境によって変わるので読み替えて下さい。
{
"spelling" : "APPLE",
"favorite" : true,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/13"
},
"word" : {
"href" : "http://localhost:8080/api/words/13"
}
}
}
もう一度そのレコードを取得してみましょう。
Pathにidを連結すると、そのレコードにアクセスできます。
$ curl http://localhost:8080/api/words/13
{
"spelling" : "APPLE",
"favorite" : true,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/13"
},
"word" : {
"href" : "http://localhost:8080/api/words/13"
}
}
}
レコードを更新してみます。
-dで指定するJSON部分に、idを除くEntityの全ての項目を指定し、idを指定したPathへPUTすると更新できます。
下ではAPPLEからappleへ更新しました。
$ curl -X PUT -H "Content-Type:application/json" -d '{ "spelling": "apple", "favorite": false }' http://localhost:8080/api/words/13
{
"spelling" : "apple",
"favorite" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/13"
},
"word" : {
"href" : "http://localhost:8080/api/words/13"
}
}
}
レコードを削除してみます。
idを連結したPathへDELETEすると、削除できます。
$ curl -X DELETE http://localhost:8080/api/words/13
検索してみます。
とりあえず検索するために、レコードを3件登録します。
curl -X POST -H "Content-Type:application/json" -d '{ "spelling": "apple", "favorite": true }' http://localhost:8080/api/words
curl -X POST -H "Content-Type:application/json" -d '{ "spelling": "apricot", "favorite": true }' http://localhost:8080/api/words
curl -X POST -H "Content-Type:application/json" -d '{ "spelling": "pineapple", "favorite": false }' http://localhost:8080/api/words
検索してみます。
検索のPathはsearchにRepositoryのメソッド名を連結します。
検索キーは、クエリ文字列に連結します。
SQLのLike条件のワイルドカード文字に当たる%は%25にエンコードして指定します。
これでappleで終わるspellingのレコードを検索しています。
$ curl http://localhost:8080/api/words/search/findBySpellingLikeOrderBySpellingAsc?spelling=%25apple
{
"_embedded" : {
"words" : [ {
"spelling" : "apple",
"favorite" : true,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/14"
},
"word" : {
"href" : "http://localhost:8080/api/words/14"
}
}
}, {
"spelling" : "pineapple",
"favorite" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/16"
},
"word" : {
"href" : "http://localhost:8080/api/words/16"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/words/search/findBySpellingLikeOrderBySpellingAsc?spelling=%25apple"
}
}
}
参考
Sample Repository
https://github.com/quwahara/SSP37/tree/600-rest