初心者向け × React × Spring Boot × API × データの流れ
はじめに
業務の詳細設計工程で、React(SPA)と Spring Boot を使った API のアプリケーション仕様を作成しているのですが、レビューを受けるたびに 「指摘の意図がつかみにくい…」 と感じることがありました。
どこに何を書けばいいのか?
どの層がどんな役割なのか?
画面から送られてきたデータって、API の中でどう変身していくのか?
このあたりが 自分の中で整理しきれていない と気づいたんです。
そこで、
「画面(React) → API(Spring Boot) → DB」までの一連のデータの流れを、
できるだけ抽象的に・シンプルにまとめてみたら、
急に腑に落ちてスッキリした瞬間がありました。
この記事では、その “理解の地図” を私なりに整理して共有してみます。
厳密な技術用語を追いかけ始めると逆に混乱しやすいので、
ざっくり「役割」と「データの形の変化」をまとめています。
データの流れ
この記事では下記のイメージ図のような「React(画面) → Spring Boot(API) → DB(倉庫)」というデータの往復が、どんな形で行われているか をざっくりイメージできるようにまとめます。
ざっくり用語説明
ここでは、これから出てくる言葉を
「専門用語ガチ説明」ではなく、感覚的に理解できるように
ざっくり紹介します。
React(リアクト)[画面を作る子]
JavaScript でつくられた “画面側のプログラム”。
ボタンを押したり、検索したりすると、画面の見た目を更新してくれます。
アプリの「見た目と操作」を担当する子。
Spring Boot(スプリングブート)[サーバーの頭脳]
Java でつくられた “サーバー側のプログラム”。
React からのお願い(API 呼び出し)を受け取って、DB のデータを取ってきたり、保存したりします。
アプリの「中身や処理」を担当する子。
SPA(Single Page Application)
ページ全体を毎回つくり直さずに、必要な部分だけを付け替える仕組み のこと。
普通の Web サイト:
リンクを押すたびに、ページが丸ごと “ガバッ” と切り替わる。
SPA:
画面はそのままで、中身(データ)だけ更新する。
イメージはこんな感じです。
スマホアプリみたいに、画面がなめらかに切り替わる。
React くんは、この「部分だけ更新」が得意です。
API(エーピーアイ)
アプリ同士が会話するための “窓口”。
React → Spring Boot に対して、
- 「データちょうだい」
- 「これ登録して〜」
- 「一覧を返して」
などとお願いする場所です。
JSON(ジェイソン)
React(JavaScript)と Spring Boot(Java)は、小学生レベルで言うと “別の言語の国の人” です。
そのため、共通語(英語的な存在)= JSON を使って会話します。
イメージ:
日本人(React)とアメリカ人(Spring Boot)が、英語(JSON)を使って会話する感じ。
流れとしては、こんな感じです。
React(JavaScript語) → JSON(共通語) → Spring Boot(Java語)
JSON の例:
{ "name": "山田", "number": 1001 }
DTO(Data Transfer Object)
**Spring Boot が JSON を受け取るとき・返すときに使う「データの型(テンプレート)」**です。
- 「この項目があって、型はこれです」
- 「この形で画面からデータを受け取ります」
- 「この形で画面に返します」
という “データの設計書・ひな形” のような役割を持っています。
実際の変換のイメージはこうです。
- React から JSON が送られてくる
- Spring Boot が DTO というテンプレートを見ながら「この値はここ、この値はここ」と自動で当てはめる
- その結果として 「中身の入った DTO」 が Controller に渡される
DTO そのものが翻訳しているのではなく、Spring Boot が DTO を参考にして翻訳してくれているイメージです。
○○Request や ○○Response というクラス名で登場します。
Entity(エンティティ)
DB(巨大な倉庫)の中にしまわれている “商品” に貼られた説明ラベル のようなものです。
「これは選手」
「id は何番で、名前は何で…」
というように、DB の 1 行をそのまま Java で表した姿 です。
Controller(コントローラー)[受付係]
外から届いた JSON を、Spring Boot によって DTO に自動変換してもらった状態で 受け取る係です。
- 受け取った DTO から必要な情報を読み取り
- 「どの Service に仕事を頼むか」を決めて依頼し
- 帰ってきた結果を画面に返す
という 受付係(窓口係) の役割を持ちます。
Service(サービス)[業務ロジック担当]
アプリの「やりたいこと」を具体的に決める担当です。
- どのデータを DB から取る?
- どう組み立てる?
- 条件に合うかの判断は?
- 最後にどんな情報を返す?
といった、アプリの業務処理の中心を担います。
Repository(リポジトリ)[倉庫係]
DB 倉庫の “倉庫係” です。
Service くんに、
- 「この商品(Entity)を取ってきて!」
- 「この商品を倉庫にしまっておいて!」
と頼まれたら、DB(巨大な倉庫)に走っていって、商品(Entity)の出し入れをしてくれます。
DB(データベース)
データがぎっしりしまわれている 巨大な倉庫です。
Repository くんだけが直接出入りできます。
データの流れ(全体イメージ)
流れをステップごとにやさしく説明
① React(画面)から JSON を送る(依頼を投げる)
React(画面側)は、ユーザーの入力内容を
共通語である JSONにして Spring Boot に送ります。
イメージは:
「このデータでお願いします!」と
メモを Spring Boot に渡す感じです。
② Spring Boot が JSON → DTO(受信用)へ自動変換
Spring Boot は受け取った JSON を
対応する DTO(受け取り専用の型)へ自動で変換します。
Controller が変換しているのではなく、
Spring Boot の内部仕組みが翻訳を担当しています。
③ Spring Boot が DTO を Controller に渡す
変換された DTO は
そのまま Controller(受付係)に自動で注入されます。
Controller は「最初から DTO になった状態」でデータを受け取り、
JSON を直接触る必要はありません。
④ Controller が DTO をもとに Service に処理を依頼
Controller は受け取った DTO の内容を確認し、
- 何をしたいのか?
- どんな処理が必要か?
を判断して Service に処理を依頼します。
Controller は「受付と振り分け係」なので、
余計なロジックは持ちません。
⑤ Service が DTO を Entity にして Repository に依頼
Service は業務の中心となる判断を行い、
- どの商品(データ)を取るべきか
- どの Entity を使って倉庫(DB)を探すか
を決めて、
DTO → Entity に変換した上で Repository に依頼します。
⑥ Repository が DB から Entity を取り出し、Service に返す
Repository(倉庫係)は、
指定された Entity の条件を使用して DB へアクセスし、
- 該当するレコードを取得
- Java 表現である Entity にして
Service に返します。
⑦ Service が Entity を DTO(返却用)に組み直す
Service は取得した Entity をもとに、
- 表示に不要なものは除く
- 必要な形に整える
- 読みやすい形へ加工する
といった処理をして、
画面向けの DTO(返却用の DTO)に組み直します。
⑧ Service が組み立てた DTO を Controller に返す
Service で作られた DTO は
Controller に渡されます。
Controller は、変換済みで綺麗に整った DTO を
ただ受け取るだけです。
⑨ Controller が DTO を Spring Boot に戻す
Controller は、受け取った DTO を
Spring Boot の仕組みに渡します。
(ここで Controller は変換せず、
単に DTO を返しているだけ。)
⑩ Spring Boot が DTO → JSON に自動変換
Spring Boot は返すときも
DTO → JSON へ自動変換します。
開発者が変換コードを書く必要はありません。
⑪ React(画面)に JSON が返却され、部分更新される(SPA)
最後に JSON が React に返り、
React は必要な部分だけサッと更新します。
ページ全体を作り直すのではなく、
SPAらしい「なめらかな部分更新」がここで行われます。
一番大事なポイント(ここだけ覚えればOK)
データは旅をしながら、形を変えていきます。
- 画面からは JSON として送られる
- Spring Boot が DTO(テンプレ) に当てはめて Controller に渡す
- Service はその情報を使って Entity(倉庫の商品) を扱いながら業務ロジックを回す
- 最後は DTO → JSON に戻して画面へ返す
そして、それぞれの役割はこんな感じです。
- React:画面と操作担当
- Spring Boot:サーバーの頭脳
- Controller:受付係(外との窓口)
- DTO:データの型・テンプレート
- Service:業務ロジック
- Repository:倉庫係(DB出し入れ)
- Entity:倉庫の商品ラベル
- DB:巨大な倉庫
なぜこんなに役割が分かれているのか?
ここまで読んでみると、
「Controller と Service と Repository に分かれているけど、
一つのクラスで全部やればいいのでは?」
と感じるかもしれません。
でも、役割を分けるのにはちゃんと理由があります。
それは アプリを「壊れにくく」「分かりやすく」「直しやすく」するため です。
-
それぞれが得意な仕事だけに集中できる
Controller:受付だけ/Service:頭脳(考えるところ)だけ/Repository:倉庫の出し入れだけ。
仕事を分けておくと、1つの変更が他に影響しにくくなるんです。 -
修正や追加がしやすくなる
例:入力チェックを変えたい → Controller を見るだけ
処理内容を変えたい → Service だけ手直し
DB の構造が変わった → Repository だけ修正
どこを直せばいいかすぐ分かる=メンテナンスが楽 になります。 -
テストがしやすくなる
役割が混ざっているとテストが大変ですが、Controller/Service/Repository のテストと分けて確認できるので、壊れにくいアプリになるんです。 -
チーム開発でも迷わない
役割ごとに担当できるので、大人数の開発でも混乱しにくい作りになっています。 -
「責務が分かれていると理解が深まる」
どの層が何をしているのか、データがどんな形で流れているのかが 明確に見えるようになります。設計書を書くときにもすごく役に立ちます。
おわりに
React(画面)から始まり、Spring Boot の Controller → Service → Repository → DB へと進むデータの旅は、いくつもの役割が支え合って成り立っています。
最初は複雑に見えるけれど、それぞれが得意分野だけを担当することで、
- 直しやすく
- 壊れにくく
- 分かりやすく
そんな“丈夫でわかりやすいアプリ”を作れるようになっています。
もしこの記事が、
「API ってどう動いてるの?」
「データってどんな形で流れるの?」
というモヤモヤを少しでも軽くできたなら、とてもうれしいです。
Discussion