[A-00206] Spring Journey(Java)
spring frameworkをジャーニーする記事です。
とりあえずいろんなspringの機能を使って色々作ってみたいと思います。
・RestAPIを設計する
OpenAPI Specificationを作成してRestAPIを設計しましょう
とりあえず下記の内容で作成しました。手始めのAPIなので簡単かつ適当に作りました。
openapi: 3.0.3
info:
title: "Person Information API"
version: "1.0.0"
servers:
- url: http://localhost:8080
paths:
/api/person/{id}:
get:
summary: Get a person info by ID
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Numeric ID of the person to get
tags:
- person
operationId: getPerson
・RestAPIを作成する
とりあえずrest-apiをspringbootで作成してみます。
まずGetメソッドを作ります。Personモデルを返すコントローラを作成します。
package com.example.rest.api.cotroller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.rest.api.model.Person;
@RestController
@RequestMapping(value="/api/person")
public class RestSvcPersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable int id) {
// TODO 後ほどcoreサービスを作成する
Person p = new Person();
p.setId(1);
p.setName("Satoshi Tajima");
p.setAge(14);
p.setCountry("Japan");
return p;
}
}
package com.example.rest.api.model;
import lombok.Data;
@Data
public class Person {
private int id;
private String name;
private int age;
private String country;
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.rest.api</groupId>
<artifactId>demo-rest-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-rest-api</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ディレクトリ構成は下記のようにしてます。
mavenビルドして起動します。
mvn clean install
java -jar target/demo-rest-api-0.0.1-SNAPSHOT.jar
実行できたらcurlを実行してGetリクエストします。下記のようにJSONが返ってきたら成功です。
$ curl -X GET http://localhost:8080/api/person/1
{"id":1,"name":"Satoshi Tajima","age":14,"country":"Japan"}
・Dockerで動かしてみる
次にデプロイするためのDockerfileを作成します。Dockerを用いて下記のようなイメージでSpringBootを動かします。
FROM openjdk:21
WORKDIR /usr/src/myapp
COPY target/demo-rest-api-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
docker build -t hello-app-java .
docker run -it --rm --publish 8080:8080 --name my-running-app hello-app-java
上記を実行すると、ローカルの8080ポートにフォワードされますので同じようにlocalhost:8080にリクエストを飛ばすと同じ結果が返ってきます。
・Kubernetesで動かしてみる
ローカルからkubernetesのservice,deploymentにアクセスしてrestapiにリクエストしたいので下記のyamlファイルを作成します。kubernetesクラスターのアーキテクチャは下記の通りです
apiVersion: v1
kind: Service
metadata:
name: hello-java-app-service
spec:
type: LoadBalancer
selector:
app: app
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: hello-app-java
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
下記のコマンドを実行します。
kubectl apply -f k8s-deployment.yml
kubernetesのservice,deploymentを確認します。
$ kubectl get pods,services,deployments
NAME READY STATUS RESTARTS AGE
pod/app-5df45cbb69-hwxk7 1/1 Running 0 18m
pod/httpd-58f4986b-sjwjw 1/1 Running 3 56d
pod/nginx-58fdfc99cd-zz9kr 1/1 Running 2 (39m ago) 56d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hello-java-app-service LoadBalancer 10.106.199.164 localhost 80:30713/TCP 18m
service/httpd-svc ClusterIP 10.111.22.101 <none> 8090/TCP 56d
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 275d
service/nginx-svc ClusterIP 10.102.32.169 <none> 8080/TCP 56d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/app 1/1 1 1 18m
deployment.apps/httpd 1/1 1 1 56d
deployment.apps/nginx 1/1 1 1 56d
localhost:80に対してリクエストを実行すると下記のように動きます。
$ curl localhost:80/api/person/1
{"id":1,"name":"Satoshi Tajima","age":14,"country":"Japan"}
・RestAPI(microservice)を設計する
次にしっかりとしたRestAPI(ちゃんとCRUD機能がある)を作成してみたいと思います。
設計する客体として学生を管理するAPIをイメージして作ります。
//TODO
・API Gatewayを作成する
API Gatewayを作成して各RestAPIへのRoutingを作りたいと思います。
コメントを残す