REST-APIを作ってみる(Java+SpringBoot編その1)

2023/1/22

(最終更新: 2023/1/22

アイキャッチ画像

はじめに

REST-APIを作ってみるシリーズ第四弾。

Node.jsとPythonとSpringBootの基礎を勉強したいので、基本的なAPIをJava(SpringBoot)で作ってみる。

Eclipseは使わずに、VSCodeで開発できるようJavaの環境構築も行なう。

Springから派生して、Javaの設計思想について学ぶことが多そうなので、今回はHTTPサーバを作るところまでで「その1」とする。

Serviceクラス/Controllerクラス/Entity/三層構造アーキテクチャ/MVCモデル/Bean/DAO/シングルトン等々はその2として勉強予定。

前提

  • OS:Windows11
  • 開発環境:VSCODE Extension Pack for Java
  • Open JDK 19.0.1
  • ビルドツール:MAVEN(apache-maven-3.8.7)
  • Spring Boot 3.0.1

SpringBootとは:Javaのフレームワーク

SpringBootとは、Javaのフレームワークの一種である。後述するSpring Frameworkの環境構築を簡単に行うためのフレームワーク。

Spring Frameworkはオープンソースのフレームワークで、WEBシステムの開発に向いている。超有名なフレームワーク。DI(Dependency Injection:依存性の注入)とAOP(Aspect Oriented Programming:アスペクト指向プログラミング)が特徴となるらしい。(詳細は別途勉強。。)

一般的にSpringといえばSpring Frameworkのことで、以下のような機能を多数含んでいる。

  • 環境構築用のSpring Bootフレームワーク
  • 機能を提供するフレームワーク
    • Sprinv MVC:
    • Spring Data:データアクセス機能
    • Spring Security:認証認可機能
  • DI/AOPを実現する機能

ビルドツール

ビルドツールは

  • MAVEN:ビルドツール
  • GRADLE:ビルドツール(MAVENの改良版)

等がある。

必要なライブラリのインストール、依存関係のあるライブラリのインストール、コンパイル、自動テスト、jarファイルの作成などを一括で実行してくれる。

実施内容①:Javaの環境構築

そもそも、Java自体、まともに勉強したのが数年前のため、環境構築からおさらいする。

参考資料

Java in Visual Studio Code

VSCode拡張機能をインストール

VSCodeのインストールは完了していたので、拡張機能のインストールから実施。

Extension Pack for Java - Visual Studio Marketplace

Open JDKをインストール

公式サイトからzipファイルをダウンロード。

https://jdk.java.net/19/

公式ページ

WindowsのC:\直下に展開した。

MAVENのインストール

公式サイトからzipファイルをダウンロードし、C:\直下に展開した。

https://maven.apache.org/download.cgi

MAVEN

環境変数・パスの設定

Windowsの環境変数に以下を追加する。

  • JAVA_HOMEC:\jdk-19.0.1
  • PATH:元の変数にC:\jdk-19.0.1\binを追加
  • PATH:元の変数にC:\apache-maven-3.8.7\binを追加

JAVA_HOME変数は一見なくてもよさそうだが、MAVENのREADME(C:\apache-maven-3.8.7\README.txt)に記載があるとおり、設定しておかないとmvnコマンド実行時にエラーとなる。

インストールできたことを確認する。

> javac -version
javac 19.0.1
> java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment (build 19.0.1+10-21)
OpenJDK 64-Bit Server VM (build 19.0.1+10-21, mixed mode, sharing)
> mvn -version
Apache Maven 3.8.7 (b89d5959fcde851dcb1c8946a785a163f14e1e29)
Maven home: C:\apache-maven-3.8.7
Java version: 19.0.1, vendor: Oracle Corporation, runtime: C:\jdk-19.0.1
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

Javaの基本プログラムを実行してみる

参考資料

以下チュートリアルからソースコードを借りています。
Getting Started with Java in Visual Studio Code

Hello.javaファイルを作成する。

workspace/helloWorld/Hello.java
/**
 * Hello
 * ターミナルにHelloと表示するプログラム
 */
public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello"); 
  }
}

PowerShellでコンパイルのために

> javac Hello.java

を実行する。コンパウイルされてHello.classというファイルが作成されるので、javaコマンドで実行する。

> java Hello
Hello

Javaの実行を確認できた。

実施内容②:SpringBootでプロジェクト開始し、Webサーバを作成

HTTPリクエストを受け付けられるWebサーバを作成する。

参考資料

ここからは以下のチュートリアルに従って実施していく。

Spring | Spring Quickstart Guide

初期プロジェクト生成

公式が提供している初期化ツールで、画像のように設定して「GENERATE」によりzipファイルをダウンロードし、解凍する。

初期化ツールURL:https://start.spring.io/

設定値

ポイント

  • Dependenciesは「Spring Web」に設定する。
  • ProjectはMavenに設定する。

デモ用コード作成

DemoApplication.javaを書き換える。

src\main\java\com\example\demo\DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

  @GetMapping("/hello")
  public String hello(@RequestParam(value = "name", defaultValue = "World")  String name){
    return String.format("Hello %s!", name);
  }

}

(解説)アノテーションとは

アノテーションは、注記・注釈の意味であり、クラスやメソッド、変数に付与することができる。@で始まる。

有名なものとしては、@Overrideがある(必ずオーバーライドしなくてはいけないメソッドにをつけることで、オーバーライドしそびれたらエラーになるようにする。)

アノテーションを作りたい場合は@interfaceで定義できる。値を保持することもできる。

public @interface CreateAnnotation {

	String name();
	int number();
}

使う側は、@CreateAnnotation(name = "なまえ", number = 0)のようにアノテーション付与することで値を利用できる。

public class Test {

	@CreateAnnotation(name = "なまえ", number = 0) // アノテーション付与
	public static void main(String[] args) {
	}
}
  • @interfaceクラスには@Target@Retention等の「メタアノテーション」をつける必要があるようだが、割愛。
  • アノテーションインターフェースに渡す変数名をvalueにしておくと、付与側で@CreateAnnotation("なまえ")のように変数名なしで渡せる。

(解説)インポートされているSpringApplicationクラス

  • SpringApplication:メインメソッドからSpringアプリケーションを起動するクラス。メインメソッドで使われている、runメソッドを持っている。

(解説)利用されているアノテーション

  • @SpringBootApplication:このクラスがSpringBootの「アプリケーションクラス」であることを示す。このようにアノテーションを示すことで、必要なコンポーネントをすべて自動で読み込んで使えるようにしてくれる。
  • @GetMapping:HTTP GETリクエストを特定のハンドラーメソッドにマッピングする。値として、今回は"/hello"が渡されている。ここで入れた値は、パスマッピングに利用される。(@GetMapping@RequestMapping(method = RequestMethod.GET) である。)
  • @RequestParam:クエリパラメータを設定できる。メソッドの引数をWebリクエストパラメーターにバインド(割り当て)する必要があることを示す。
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name){}の記述では、helloメソッドの引数(String name)にアノテーションをつけることで、クエリパラメータ名とデフォルトの値を設定している。

ビルド、実行

PowerShellで以下コマンドを実行する。

> .\mvnw spring-boot:run.\mvnw spring-boot:run

公式チュートリアルには、

> mvnw spring-boot:run

と書いてある。コマンドプロンプトだとこのままでOKなのだが、PowerShellで実行しようとすると下記のようなメッセージが出てしまうため、.\mvnwコマンドを使うこと。

Suggestion [3,General]: コマンド mvnw は見つかりませんでしたが、現在の場所に存在します。Windows PowerShell は、既定では 、現在の場所からコマンドを読み込みません。このコマンドを信頼する場合は、".\mvnw" と入力してください。詳細については、"get-help about_Command_Precedence" と入力してヘルプを参照してください。

localhost:8080/helloに、API打鍵ツールを使ってアクセスすると、平文で「Hello World!」が返却されていることがわかる。

Postman応答が帰ってくる

ヘッダ ヘッダ

実施内容③:SpringBootでREST-APIを作成する

JSON形式で返却できるAPIを作成する。

初期プロジェクト作成

初期化ツールでプロジェクトを作るところから始める。

REST-APIプロジェクト作成

リソース表現クラスを作成

リソースを表現するクラスを作成する。

src\main\java\com\example\greetingapi\restservice\Greeting.java
package com.example.greetingapi.restservice;

public record Greeting(long id, String content) {
}

Greetingの型を定義した。

getterを持っており、インスタンス作成時にコンストラクタを呼び出して値を設定する。

(解説)Javaのrecordクラスとは

単純なデータ構造のみを持つクラスをシンプルに記述するためのクラス。Java16から正式実装されている。

package com.example.greetingapi.restservice;

public record Greeting(long id, String content) {
}
  • フィールド自動生成: private finalのフィールドを自動生成できる。今回はidcontentを自動生成できる。
  • コンストラクタ自動生成: 自動生成されたフィールドに値を設定するコンストラクタが自動生成される。実装すれば「コンパクト・コンストラクタ」を利用可能。
  • getterの自動生成: getterが自動生成される。
  • equalshashCodeの自動オーバーライド: 通常は、インスタンスが違えばequalsfalseとなるが、自動オーバーライドすることにより、同じ値に対してtrueを返すようオーバーライドしてくれる。
  • toStringの自動オーバーライド: 通常は、インスタンスの情報が返却されるが、クラス名、フィールド名、フィールドの中身を返却できるようオーバーライドしてくれる。

(解説)コンパクト・コンストラクタとは

recordで利用可能なコンストラクトの宣言方法。

record Greeting(long id, String content) {
  public Greeting {
    if (id <= 0 || content == null) {
      throw new java.lang.IllegalArgumentException(
          String.format("Invalid dimensions"));
    }
  }
}

リソースコントローラを作成

Springの決まりとして、HTTPリクエストはコントローラによって処理する。コントローラであることを@RestControllerで示すことができる。

@RestControllerを付与することによって、GreetingオブジェクトがJSONとしてHTTPレスポンスに書き込まれる。

src\main\java\com\example\greetingapi\restservice\GreetingController.java
package com.example.greetingapi.restservice;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

  private static final String template = "Hello, %s!";
  private final AtomicLong counter = new AtomicLong();

  @GetMapping("/greeting")
  public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name){
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
  }

}

メインメソッド作成

ひな形から特に変更せず。

package com.example.greetingapi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GreetingapiApplication {

	public static void main(String[] args) {
		SpringApplication.run(GreetingapiApplication.class, args);
	}

}

ビルド・実行

ビルドしてjarファイルを作成する。(greetingapi直下。srcフォルダのある場所)

> ./mvnw clean package

jarファイルが作成された場所がメッセージから確認できた。

[INFO] Building jar: C:\Users\~~~~~~\greetingapi\target\greetingapi-0.0.1-SNAPSHOT.jar

実行する。

> java -jar target/greetingapi-0.0.1-SNAPSHOT.jar

Postmanで見るとJSONでデータ返却されていることがわかる。

実行結果

ヘッダ ヘッダ

繰り返し呼び出すと、idがインクリメントされていく。

実行結果7

おわりに

JavaのフレームワークSpring Bootを利用して、HTTPリクエストを受け付けることができた。

まじめにJavaを勉強しようとすると、知らないことがかなり出てくるが、、アーキテクチャ周りは知っておいて損がないと思うので、なるはやで「その2」を書けるようにしたい。

参考資料



個別連絡はこちらへ→Twitterお問い合わせ

プロフィール

プロフィールイメージ

はち子

事業会社のシステム部門で働きはじめて5年目の会社員。システム企画/要件定義/システムアーキテクチャ等。

Twitter→@bun_sugi

過去の記事について

はてなブログに掲載の記事(主にプログラミングメモ)についてはこちらに掲載しております。(本ブログに移行中)

タグ一覧

関連記事

Copyright© 2023, エンジニアを目指す日常ブログ

お問い合わせ|プライバシーポリシー