3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

HerokuAdvent Calendar 2020

Day 9

大急ぎでAPI+SPA構成のアプリを立ち上げる(Spring Boot&Heroku編)

Last updated at Posted at 2020-12-09

はじめに

「PoCやるんだけど、こういうの用意できない?
 とりあえず動けばいいから明日までに

Picture1.png

どうする

いやです

という言葉を飲み込んで

さっさと作っていきましょう。
いろいろ選択肢があるのは存じていますが、当方JavaエンジニアなのでバックエンドはSpring Bootです。
インフラには、忙しいときの心強い味方 Heroku を使います。

Picture2.png

環境

OS

  • macOS Catalina

ツール・ソフトウェア

バックエンドから

Spring Initializrで雛形を生成します。
PCの都合でJavaは8。
Screen Shot 2020-12-01 at 21.10.08.png

Dependencies(ライブラリ)ですが、Spring WebがあればとりあえずOK。
Lombokは…IDEの設定にひと手間かかるのでやめときます。急いでるので。

zipをダウンロード&解凍し、任意のIDEで開いたら、まずダミーデータを返すAPIを作っていきます。

com.exampleパッケージの下にcontrollermodelを追加し、以下のクラスを作成します。

Screen Shot 2020-11-30 at 0.12.37.png

package com.example.demo.model;

// 部署クラス
public class Department {
    public String name;

    public Department(String name) {
        this.name = name;
    }
}
package com.example.demo.model;

// 社員クラス
public class Employee {
    public String name;
    public Department department;

    public Employee(String department, String name) {
        this.department = new Department(department);
        this.name = name;
    }
}
package com.example.demo.controller;

import com.example.demo.model.Employee;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    @GetMapping // 『GET /api/employees』で実行されるようにマッピング
    public List<Employee> getEmployees() {
        List<Employee> results = new ArrayList<>();
        results.add(new Employee("営業", "社員 太郎"));
        results.add(new Employee("開発", "社員 次郎"));
        return results;
    }
}

DemoApplicationを起動します。
IDEの機能でも、コマンドラインから./gradlew bootRunでもOKです。

Screen Shot 2020-11-30 at 1.08.25.png
Screen Shot 2020-11-30 at 1.02.44.png

ブラウザを開き、http://localhost:8080/api/employeesにアクセス。

Screen Shot 2020-12-02 at 0.15.13.png

動いてますね。ヨシ。

Heroku上で動かす

次は稼働環境を用意します。
Heroku上にデプロイしてAPIを公開してみましょう。

リンク先でHerokuの無料アカウントを作成したら、右上のメニューから「Create new app」を選択。

Screen Shot 2020-12-09 at 19.46.19.png

好きなアプリ名を入力し、ふたたび「Create new app」をクリック。

Screen Shot 2020-11-30 at 1.37.22.png

アプリが作成されると、デフォルトで「Deployment」タブが開いてるかと思います。
デプロイ方法(Deployment method)が3つ並んでいますので、「Heroku Git」を選択。

Screen Shot 2020-11-30 at 2.03.32.png

その下に書かれている手順とコマンドに従って、アプリをデプロイします。
ざっくり言うと、gitリポジトリをローカルに作成→herokuをリモートに設定→push という流れです。
Heroku CLIのインストールを忘れずに。

Screen Shot 2020-12-01 at 2.09.01.png

HerokuはgradleとSpring Bootを自動で認識してくれるので、設定ファイルの追加等は不要です。
エラーが出ずに終了したら、「Overview」タグを開いて右側のアクティビティを確認。

Screen Shot 2020-11-30 at 2.13.17.png

無事にデプロイされたようです。
続いて右上の「Open App」ボタンをクリック。404画面が出てきますが、くじけずURLに「/api/employees」を追加。

Screen Shot 2020-12-01 at 2.11.11.png

Screen Shot 2020-11-30 at 2.16.27.png

これでOK。これ以降はpushするたびにアプリが自動で更新されていきます。便利!

DBを用意する

続いてDBですが、Herokuに任せます。
Herokuアドオンの「Heroku Postgres」は、容量は小さいながら無料・速攻でDBが使えるのです。

「Resources」タブの「Add-ons」から検索します。
プランは「Hobby Dev - Free」を選択し、さっそく作成。

Screen Shot 2020-11-30 at 2.37.10.png
Screen Shot 2020-11-30 at 2.37.21.png
Screen Shot 2020-11-30 at 2.38.52.png

あっという間にご用意されました。

DBと繋ぐ

先ほど作成したSpring Bootアプリから、DBに接続していきます。
まずはライブラリを追加しましょう。build.gradleを開き、dependenciesに以下を追加します。

	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.flywaydb:flyway-core'
	runtimeOnly 'org.postgresql:postgresql'

ORマッパーには、DBがシンプルだとラクなSpring Data JPAを選択します。
あとはPostgreSQLのドライバと、テーブル作成がラクになるのでFlywayも入れておきます。
(これらはSpring Initializrでも追加できたのですが、設定が必要になるので後回しにしました)

ここからはDBと接続するための設定です。
src/main/resources/application.propertiesに以下の行を追加します。

spring.datasource.url=spring.datasource.url=${JDBC_DATABASE_URL}

Herokuの環境変数には、DB接続用の文字列がJDBC_DATABASE_URLとして格納されています。
Heroku上で動いているときなら取得できるのですが、ローカルではできません。

ということで、Herokuから接続文字列をもらってきましょう。Herokuのドキュメントを参考に、以下のコマンドを実行。

heroku run echo \$JDBC_DATABASE_URL -a (Herokuアプリ名)

表示された「jdbc:postgresql://…」という文字列を、ローカルの環境変数に設定します。
IntelliJであれば、DemoApplication.javaを右クリック→「Edit 'DemoApplication'…」から設定できます。
application.propertiesにベタ書きでも動くのですが、GitHubなどで一般公開しないように注意してください。

Screen Shot 2020-12-01 at 23.56.46.png

続いて、コードをSpring Data JPAの形式に書き換えていきます。
もしここでクラスが見つからないというエラーが出る場合、ライブラリのダウンロードが行われていないかもしれないので、プロジェクトのビルドやIDEの再起動を試してみてください。

com.exampleパッケージの下に`repository``を追加し、以下のインタフェースを作成。

package com.example.demo.repository;

import com.example.demo.model.Employee;
import org.springframework.data.repository.CrudRepository;

public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}

modelパッケージ以下のクラスを修正。

package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.Id;

// 部署クラス
@Entity
public class Department {
    @Id
    private Integer id;

    public String name;
}
package com.example.demo.model;

import javax.persistence.*;

// 社員クラス
@Entity
public class Employee {
    @Id
    private Integer id;

    public String name;
    
    @ManyToOne
    public Department department;
}

EmployeeControllergetEmployeesも修正。
Repositoryのメソッドを使い、DBからデータを取得するようにします。

    @GetMapping // 『GET /api/employees』で実行されるようにマッピング
    public Iterable<Employee> getEmployees() {
        return employeeRepository.findAll();
    }

最後に、Flyway用のSQLを作成します。
src/main/resourcesの下にdb/migrationフォルダを作成し、中にSQLファイルを入れておくと、
アプリケーション起動時に自動でセットアップしてくれます。
Screen Shot 2020-12-01 at 23.30.45.png

-- V1_0__create_table.sql
CREATE TABLE department(
  id serial PRIMARY KEY,
  name varchar(40) NOT NULL
);

CREATE TABLE employee(
  id serial PRIMARY KEY,
  department_id integer REFERENCES department(id),
  name varchar(40) NOT NULL
);
-- V1_1__insert_data.sql
INSERT INTO department(id, name)
VALUES (1, '営業1課'),
       (2, '開発2課');

-- 自動採番のIDを強引に付与したので、シーケンス管理用の値を再設定
SELECT setval('department_id_seq', MAX(id))
FROM department;


INSERT INTO employee(id, department_id, name)
VALUES (1, 1, '社員 三郎'),
       (2, 2, '社員 四郎');

SELECT setval('employee_id_seq', MAX(id))
FROM employee;

では、もう一度アプリケーションを起動します。

Screen Shot 2020-12-01 at 23.37.00.png

しっかり動いているようです。
これをHerokuにpushすると…

git add .
git commit -am "db access"
git push heroku master

Screen Shot 2020-12-02 at 0.02.12.png

無事に反映されました。

さいごに

とりあえず大急ぎでAPIサーバをセットアップしました。
APIを誰でも実行できたり、ローカルとサーバで同じDBを参照していたりと問題は山積みですが、一旦ここで区切ります。
次回の記事では、フロントエンドも大急ぎで立ち上げていきます。

参考リンク

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?