25
22

More than 5 years have passed since last update.

QuarkusでDBと接続するWebAPI作ってみた

Last updated at Posted at 2019-03-12

目的

巷で話題のQuarkusの使い勝手を確認した内容のまとめを残します。
Get Started だけは物足りなかったのでローカルで立てたPostgreSQLをHibernateで操作するRESTのWebAPIにしてみました。

事前準備

Mavenプロジェクト

QUARKUS - CREATING YOUR FIRST APPLICATIONを先に完了させておきます。
プロジェクトの状態はこんな感じです。

$ tree ./
./
├── pom.xml
├── quarkus_quickstart.iml
└── src
    ├── main
    │   ├── docker
    │   │   └── Dockerfile
    │   ├── java
    │   │   └── com
    │   │       └── dsert
    │   │           └── quickstart
    │   │               ├── GreetingResource.java
    │   │               └── GreetingService.java
    │   └── resources
    │       ├── META-INF
    │       │   ├── microprofile-config.properties
    │       │   └── resources
    │       │       └── index.html
    │       └── application.properties
    └── test
        └── java
            └── com
                └── dsert
                    └── quickstart
                        ├── GreetingResourceTest.java
                        └── NativeGreetingResourceIT.java

PostgreSQL

適当にテーブルとかを作っておきます。
IntelliJで生成したDDLは以下のような感じです。

create database quarkus with owner quarkus;

create table if not exists users
(
    id serial not null
        constraint users_pk
            primary key,
    name varchar(255) not null
);

実装手順

依存関係

QUARKUS - EXTENSIONSの項目を参考にしながら、pom.xmlにHibernateとPostgreSQLの依存関係を追加します。
また、Get Startedのままの依存関係ではJSONでのリクエスト・レスポンスができないので、quarkus-resteasyquarkus-resteasy-jsonbに変更します。

pom.xml
<dependencies>
  ...
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-jsonb</artifactId>
  </dependency>

  <!-- Hibernate ORM specific dependencies -->
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-orm</artifactId>
    <scope>provided</scope>
  </dependency>

  <!-- JDBC driver dependencies -->
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
    <scope>provided</scope>
  </dependency>
</dependencies>

環境値

QUARKUS - APPLICATION CONFIGURATION GUIDEに記述されているように、application.propertiesで環境値の管理が可能です。
DB接続に必要な情報を以下のように記述します。

src/main/resources/application.properties
quarkus.datasource.url: jdbc:postgresql://localhost:5432/quarkus
quarkus.datasource.driver: org.postgresql.Driver
quarkus.datasource.username: quarkus
quarkus.datasource.password: quarkus-pass

ソースコード

Entity

データをマッピングする、テーブルに合うEntityオブジェクトを作成します。

src/main/java/com/dsert/quickstart/User.java
package com.dsert.quickstart;

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

@Entity(name = "users")
public class User {
    private int id;
    private String name;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Service

DB操作をするサービスクラスを作ります。

src/main/java/com/dsert/quickstart/UserService.java
package com.dsert.quickstart;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.List;

@ApplicationScoped
public class UserService {
    @Inject
    EntityManager em;

    @Transactional
    public void createUser(String name) {
        User user = new User();
        user.setName(name);
        this.em.persist(user);
    }

    public List<User> getUsers() {
        return this.em.createNativeQuery("select * from users", User.class).getResultList();
    }
}

Resource

HTTPリクエストを処理するリソースクラスを作ります。

src/main/java/com/dsert/quickstart/UserResource.java
package com.dsert.quickstart;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {
    @Inject
    UserService service;

    @POST
    public Map<String, String> createUser(User user) {
        this.service.createUser(user.getName());
        return Collections.singletonMap("message", "OK");
    }

    @GET
    public List<User> getUsers() {
        return this.service.getUsers();
    }
}

動作確認

アプリケーション起動

気軽に起動したいので、DockerImageではなく、developmentモードで起動します。

mvn compile quarkus:dev                                                                                                                                                                    6.2m
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.d-sert:quarkus_quickstart >--------------------
[INFO] Building quarkus_quickstart 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ quarkus_quickstart ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 3 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ quarkus_quickstart ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- quarkus-maven-plugin:0.11.0:dev (default-cli) @ quarkus_quickstart ---
[INFO] Using servlet resources quarkus_quickstart/src/main/resources/META-INF/resources
Listening for transport dt_socket at address: 5005
2019-03-13 08:49:58,673 INFO  [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
2019-03-13 08:49:59,282 INFO  [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 609ms
2019-03-13 08:50:05,128 INFO  [io.quarkus] (main) Quarkus 0.11.0 started in 6.638s. Listening on: http://127.0.0.1:8080
2019-03-13 08:50:05,130 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-postgresql, narayana-jta, resteasy, resteasy-jsonb]

HTTPリクエスト

POST

$ curl -X POST -H 'Content-Type: application/json' 'http://localhost:8080/users' -d '{"name": "sert"}'
{"message":"OK"}

GET

$ curl 'http://localhost:8080/users'
[{"id":5,"name":"sert"}]

最後に

本当はMySQLに繋ぎたかったのですが、MySQLのDriverがExtensionになく、
MariaDBのDriverでも上手く繋げなかったのでPostgreSQLで実施しました。
そのうちMySQLでリベンジしてみるつもりです。

25
22
1

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
25
22