LoginSignup
1
1

More than 5 years have passed since last update.

SidenでRestサービスとDBアクセス

Last updated at Posted at 2014-12-07

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でアクセスして欲しい。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1