Open9

Spring Boot & Kotlinで開発環境を整える

めなしめなし

What is this?

一通り、SpringBootを使ってバックエンドアプリケーションを構築するまでの手順をメモする。

アプリケーション構成

  • Spring Boot (RESTfull API)
  • PostgreSQL
  • Redis
  • Elasticsearch
  • Kibana

達成したいこと

  • フロントエンドに向けてOpenAPIでAPIドキュメントを渡せる
  • とりあえずユーザーとなんらかのオブジェクトを作成して、PostgreSQLおよびElasticsearchに格納できる
  • それをKibanaで統計が取れる
  • Redisを使ってステートレスなJWT認証を使える
めなしめなし

手始めにエンドポイントを一つ追加。そんでもってSecurityも設定

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/health")
class HealthController {
    @GetMapping
    fun health(): String {
        return "OK"
    }
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
    @Bean
    fun configure(http: HttpSecurity): SecurityFilterChain {
        http.authorizeHttpRequests {
            it
                .requestMatchers("/health").permitAll().anyRequest().authenticated()
        }
        return http.build()
    }
}

動いた。

次はポスグレと繋ごう。

めなしめなし

繋がった。設定はこんな感じ。ちなみにポスグレそのものはdocker-composeにしてある。サクッと立てたかったので、エントリポイントの設定とかは今のところしていない。あとでやるか………

application.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/hoge
    username: hoge
    password: hoge
  jpa:
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    hibernate:
      ddl-auto: update

docker-compose.yml(抜粋)

  postgres:
    image: postgres:16.1
    ports:
      - ${POSTGRES_PORT:-5432}:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: ${RESTART_POLICY:-unless-stopped}
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
めなしめなし

ユーザーのEntityを作成して、ddl-auto: updateで動くようにしていたと思ったら、Userテーブルの作成でこけた。
どうやらポスグレでは"user"は予約語だったらしい。@Table(name="app_users")をつけて無事解決。

めなしめなし

今度はPostリクエストが送れない。どうやらcsrfの設定が要るらしい。そもそもscrfて何じゃい……?

めなしめなし

取り合えずセキュリティ関係なことだけはわかった。一旦今後の課題としておいておこう。フロントエンド側もやる予定なのでこの本をほしい物リストへぶちこんでおく。

https://amzn.asia/d/48VrBJx

めなしめなし

とりあえず、一旦オフっておく。ほんとはapplication.ymlとかで設定できる方がいいんだろうなぁ〜〜

    @Bean
    fun configure(http: HttpSecurity): SecurityFilterChain {
        http
+            .csrf { it.disable() } // FIXME: Production should have this enabled
            .authorizeHttpRequests {
                it
                    .requestMatchers("/health", "/user/**", "/api-docs/**").permitAll().anyRequest().authenticated()
            }
        return http.build()
    }
めなしめなし

さて、次やるべきはこんなところか

  • API-DOCSの生成
  • 認証システムの構築(JWT, Basic)
    • 基本はJWTを使う
    • トークン作成の時だけBasic認証
  • ElasticsearchとSpringの繋ぎこみ
めなしめなし

API-docsを作る

とりあえず、Swagger-UIとopenapiの定義ファイルの両方が欲しかったのでこんな感じに。

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.3.0</version>
        </dependency>

入れてみたが、出てこない。ちょっと前にセキュリティをいじっていたのが原因で認証が必要になってしまっていたらしい。
とりあえず、このままだと定義ファイルが見れないのでこんな感じに変更しておいた。あとでPropertiesからこのBeanの有効無効を切り替えられるようにしておかないと……

    @Bean
    fun docsSecurity(http: HttpSecurity): SecurityFilterChain {
        http
            .securityMatcher("/swagger-ui/**", "/v3/api-docs/**")
            .csrf { it.disable() } // FIXME: Production should have this enabled
            .authorizeHttpRequests {
                it.anyRequest().permitAll()
            }
        return http.build()
    }

無事に出た。