Siden
https://github.com/taichi/siden
Hello Worldやったので、
http://qiita.com/masatsugumatsus/items/c07e13f81fea12fa590e
次は、RestとDBアクセス
Entity
Lombok使えって話しだが。。。
Book.java
import java.io.Serializable;
public class Book implements Serializable{
/**
*
*/
private static final long serialVersionUID = 6484020759599047569L;
private String isbn;
private String name;
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Resouceクラス
bodyの取り出し方が分かりません。。。
JsonライブラリはなれているからGsonを使う
BookResource.java
import java.io.IOException;
import java.nio.ByteBuffer;
import ninja.siden.App;
import ninja.siden.Renderer;
import ninja.siden.Request;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.xnio.channels.StreamSourceChannel;
import com.google.gson.Gson;
public class BookResource {
private App app;
private DBI dbi;
private Gson gson = new Gson();
public BookResource(App app, DBI dbi) {
this.app = app;
this.dbi = dbi;
}
@Override
public void defineRoutes() {
app.post(
"/books",
(req, res) -> {
String body = body(req);
Book book = gson.fromJson(body, Book.class);;
try (Handle h = dbi.open()) {
h.execute(
"MERGE INTO book(isbn, name) VALUES(?, ?)",
book.getIsbn(),
book.getName());
}
return book;
}).render(Renderer.of(gson::toJson))
.type("application/json");;
app.get("/books/:isbn",
(req, res) -> {
return req.params("isbn")
.map(isbn -> {
Book b = null;
try (Handle h = dbi.open()) {
b = h.createQuery( "SELECT isbn,name "
+"FROM book WHERE isbn=:isbn")
.bind("isbn", isbn).map(Book.class)
.first();
}
return b;
}).orElseThrow(ResouceNotFoundException::new);
}).render(Renderer.of(gson::toJson))
.type("application/json");
}
private String body(Request req) {
int size = (int) req.raw().getRequestContentLength();
ByteBuffer buff = ByteBuffer.allocate(size);
try (StreamSourceChannel reqChannel = req.raw().getRequestChannel()) {
reqChannel.read(buff);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return new String(buff.array());
}
}
main
Application.java
import javax.sql.DataSource;
import ninja.siden.App;
import org.h2.jdbcx.JdbcConnectionPool;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
public class Application {
public static void main(String[] args) {
DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test",
"username",
"password");
DBI dbi = new DBI(ds);
init(dbi);
App app = new App();
new BookResource(app,dbi).defineRoutes();
app.listen();
}
private static void init(DBI dbi) {
try(Handle h = dbi.open()){
h.execute("create table book(isbn varchar(11) primary key, name varchar(100))");
}
}
}
テスト
BookResourceSpec.groovy
package com.sidensample.mm;
import javax.sql.DataSource;
import org.h2.jdbcx.JdbcConnectionPool;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import groovyx.net.http.RESTClient
import ninja.siden.App
import spock.lang.Ignore;
import spock.lang.Shared
import spock.lang.Specification
class BookResourceSpec extends Specification {
@Shared stop
def endpoint = new RESTClient( 'http://localhost:8080/' )
def setupSpec(){
DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test",
"username",
"password");
DBI dbi = new DBI(ds);
Handle h = dbi.open();
h.execute("create table book(isbn varchar(11) primary key, name varchar(100))");
h.execute("insert into book(isbn, name) values (?, ?)", "1234", "ほんの名前");
h.close();
def app = new App()
new BookResource(app,dbi).defineRoutes()
stop = app.listen()
}
def "postのテスト"(){
when:
def resp=endpoint.post([ path: 'books',
body:[isbn:"1234",name:"abcd"],
requestContentType:"application/json"
])
def resp2=endpoint.get([ path: 'books/1234'])
then:
with(resp) {
status == 200
data.isbn == "1234"
data.name == "abcd"
}
with(resp2) {
status == 200
data.isbn == "1234"
data.name == "abcd"
}
}
def cleanupSpec(){
stop.stop()
}
}
Dropwizardよりも簡単なのは凄いな。microserviceにはいけるんではないか。
要望
・管理用の別ポート設定(多分できるけど、もう少し簡単に。。。)
・body部取得の方法(自信ない。。。)
・静的コンテンツをClasspathResourceでアクセスして欲しい。