← Spring コース
23. Spring が決めていること、決めていないこと
アプリのソースの置き方について、 が既定で決めているのは2つだけです。( を持ち、 を付けた)のとその配下から部品を探すことと、 や などの既定の置き場所です。controller や service というフォルダ名は見ず、(クラスに付ける印)で見分けます。
同じ5クラスを、層別、機能別、1か所に平置き、banana や x/y/z という名前、の4通りに置いても応答は同じでした。Next.js ではフォルダの位置が URL になり、page.tsx というファイル名に意味があります。 では URL は の引数で決まり、ファイルの場所は関係しません。NestJS はに部品を列挙しますが、Spring Boot は列挙せず配下を走査します。
落とし穴は起点です。起動クラスだけを隣のパッケージへ移すと、起動は成功し、エラーも警告も出ないまま、リクエストが 404 になりました。起点の配下に部品が無くなったからです。起点は指定で変えられるので、これは既定の話です。また2つだけというのは Web と設定ファイルの範囲のことで、データベース用のクラスの探索など、場所に意味がある箇所は他にもあります。
点線の付いた語はタップすると説明が出ます。用語集を開く →
com.example.shop.ShopApplication起動クラス。@SpringBootApplication が付いている
このパッケージの配下を走査する
banana/OrderController@RestController
x/y/z/OrderService@Service
misc/stuff/OrderRepository@Repository
フォルダ名ではなくアノテーションで見分けて登録する
GET /orders/1 → 200層別・機能別・平置きの配置と同じ応答
URL は @GetMapping の引数で決まる- 起動クラスだけを com.example.shop.app に移した変種では、起動は成功し、/orders/1 は 404 でした(各変種1回の実行)。
- Boot のリファレンスは Spring Boot does not require any specific code layout to work. と書き、起動クラスを他のクラスより上のパッケージに置くことを勧めています。例に挙げている配置は機能別です。
- 設定ファイルはクラスパス直下と config/ の下が読まれ、settings/ の下は読まれませんでした。static/ や public/ のファイルは配信され、assets/ は 404 でした。
- Next.js の公式ドキュメントは Folders define URL segments. と書いています。ルーティングに使う場所以外の整理の仕方については unopinionated だとしています。
サンプルコード(フレームワーク環境が必要なため表示のみ)
// フォルダ名(パッケージ名)を banana にした変種。Spring Boot 4.1.1 / JDK 25(ログ出力の1行は省略)
package com.example.shop.banana;
import com.example.shop.things.Order;
import com.example.shop.x.y.z.OrderService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
// Spring が見るのはこの印。controller というフォルダ名は見ていない
@RestController
public class OrderController {
private final OrderService service;
public OrderController(OrderService service) {
this.service = service;
}
// URL を決めるのはこの引数。ファイルの置き場所は URL に関係しない
@GetMapping("/orders/{id}")
public Order get(@PathVariable long id) {
return service.find(id);
}
}
// 起動クラスは com.example.shop.ShopApplication(このパッケージの上)
// $ curl http://localhost:8080/orders/1
// {"id":1,"item":"apple","quantity":3}
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗