本文へスキップ本文へスキップ
Web開発

APIって結局何?フロントとバックエンドの間で何を渡してるのか、めちゃくちゃ分かりやすく整理してみた

APIって結局何?フロントとバックエンドの間で何を渡してるのか、めちゃくちゃ分かりやすく整理してみた
目次

APIって結局何?フロントとバックエンドの間で何を渡してるのか、めちゃくちゃ分かりやすく整理してみた

Next.jsやLaravelを触っていると、APIという言葉が普通に出てきます。

const res = await fetch('/api/articles')
const data = await res.json()

みたいなコードもよく書きます。

自分もAPIを作ったり呼んだりはしています。

でも、

APIって何?

と改めて聞かれると、

フロントとバックエンドでデータをやり取りするやつ。

くらいの説明になりがちです。

間違いではないのですが、それだけだと、

endpointって何?
GETとPOSTは何が違う?
headerとbodyは何を入れる?
JSONはAPIそのもの?
200とか404は誰が返してる?
認証はどこで入る?

あたりが全部バラバラに見えます。

そこで今回は、APIを初めて触る人でも、

ブラウザから注文を出して、バックエンドが処理し、結果が返ってくる

という一本の流れで理解できるように整理してみます。


そもそもAPIは「ソフトウェア同士の受付ルール」

APIは Application Programming Interface の略です。

MDNでは、APIを、あるソフトウェアと別のソフトウェアやハードウェアがやり取りするための機能や規則の集まりとして説明しています。

参考: https://developer.mozilla.org/ja/docs/Glossary/API⁠(外部サイト)

つまりAPIは、Webサーバーだけの言葉ではありません。

ブラウザには、

  • Geolocation API

  • Web Animations API

  • Fetch API

などがあります。

OSやライブラリにもAPIがあります。

なので、

API = REST API

API = JSONを返すURL

ではありません。

APIという言葉自体はもっと広く、

「このルールで呼んでくれれば、この機能を使えます」というソフトウェア同士の窓口

くらいに考えると分かりやすいです。

その中でもこの記事では、Web開発でよく使う HTTP API を中心に見ていきます。


Web APIは「レストランの注文」で考えると分かりやすい

少し雑に例えます。

フロントエンドをレストランの客。

バックエンドを厨房。

APIをホールスタッフや注文窓口だとします。

客が厨房へ直接入り、

冷蔵庫開けて、肉出して、自分で焼きます

とは普通なりません。

客はメニューを見て、

ハンバーグ1つください

と注文します。

注文を受けた側が厨房へ伝える。

厨房が処理する。

完成した料理が客へ返ってくる。

Web APIもかなり似ています。

フロントエンド
   ↓ request
API
   ↓
バックエンドの処理
   ↓
DBなど
   ↓
API
   ↓ response
フロントエンド

フロントエンドがDBへ直接、

usersテーブルの3行目を今から勝手に書き換えます

とやるのではなく、

このユーザー情報を更新してください

という決められた窓口へrequestを送ります。

バックエンド側で、

  • 入力は正しいか

  • ログインしているか

  • このデータを変更する権限があるか

  • DBへ何を保存するか

を判断し、結果を返します。

APIって結局何?フロントとバックエンドの間で何を渡してるのか、めちゃくちゃ分かりやすく整理してみた

requestとresponse、この2つがまず基本

HTTPはクライアントとサーバーの間でメッセージをやり取りします。

MDNでは、クライアントから送られるメッセージを request、サーバーから返されるものを response と説明しています。

参考: https://developer.mozilla.org/ja/docs/Web/HTTP/Guides/Overview⁠(外部サイト)

たとえば記事一覧を取得するとします。

フロント側から、

GET /api/articles

というrequestを送る。

バックエンドが処理して、

HTTP/1.1 200 OK
Content-Type: application/json

と一緒に、

[
{
"id": 1,
"title": "APIって結局何?"
}
]

のようなresponseを返す。

かなり単純化すると、

request = お願い

response = そのお願いへの返事

です。

HTTPの標準であるRFC 9110でも、クライアントがrequestを作成し、サーバーがそれを解釈してresponseを返すモデルとして定義されています。

参考: https://www.rfc-editor.org/rfc/rfc9110.html⁠(外部サイト)


endpointは「どの窓口に頼むか」

APIを触っているとendpointという言葉が出てきます。

たとえば、

GET /api/articles
GET /api/articles/123
POST /api/articles

のようなURLです。

厳密にはAPI設計によって表現は変わりますが、初心者向けには、

endpoint = APIへアクセスする窓口の場所

くらいで考えると分かりやすいです。

レストランで、

注文受付

会計

テイクアウト受付

が別れているようなものです。

URLだけでなく、次に出てくるHTTP methodとセットで、

「どこに、何をしてほしいのか」

を表します。


GETとPOSTは「同じURLでもお願いの種類が違う」

HTTPにはrequest methodがあります。

RFC 9110では、methodはクライアントがそのrequestで何をしたいのかを示す主要な情報として定義されています。

参考: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods⁠(外部サイト)

よく使うものはこのあたりです。

GET

データを取得したい。

GET /api/articles

なら、

記事一覧をください

というイメージです。

POST

データを送って、サーバー側で処理してほしい。

POST /api/articles

なら、

この内容で新しい記事を作ってください

のような用途です。

PUT / PATCH

既存データを更新するときに使われます。

PUTとPATCHは同じ意味ではありません。

一般にPUTは対象の表現全体を置き換える意味を持ち、PATCHは部分的な変更に使われます。

DELETE

対象を削除したい。

DELETE /api/articles/123

なら、

ID 123の記事を削除してください

というrequestです。

ただし、

GETなら必ずDBをSELECTする

POSTなら必ずINSERTする

という意味ではありません。

HTTP methodはrequestの意味・意図を表すものです。

実際にサーバー内部で何をするかはAPI側の実装によります。


headerは「注文票の端に書いてある補足情報」

requestにはURLやmethodだけでなく、headerも付けられます。

MDNではHTTP headerを、requestやresponseに追加情報を渡すためのものとして説明しています。

参考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference⁠(外部サイト)

たとえば、

Content-Type: application/json
Authorization: Bearer xxxxx
Accept: application/json

のような情報です。

レストランの注文で例えるなら、

テイクアウトです

アレルギーがあります

会員番号はこれです

みたいな注文そのものとは別の付帯情報に近いです。

Content-Type

bodyに入っているデータが何形式なのかを伝えます。

Content-Type: application/json

なら、

このbodyはJSONです

という意味です。

Authorization

認証情報を送るときによく使われます。

たとえばBearer tokenを使うAPIなら、

Authorization: Bearer TOKEN

のように送ります。

API側はこれを見て、

誰から来たrequestなのか

この操作を許可していいのか

を判断します。


bodyは「実際に渡したい中身」

POSTやPATCHなどでは、request bodyへデータを入れることがあります。

たとえば新しい記事を作るなら、

{
"title": "APIって結局何?",
"status": "draft"
}

のようなJSONを送れます。

JavaScriptなら、

await fetch('/api/articles', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'APIって結局何?',
status: 'draft',
}),
})

のような形です。

ここで、

API = JSON

ではないことも覚えておきたいです。

HTTPではJSON以外にも、

  • HTML

  • plain text

  • form data

  • XML

  • 画像などのbinary data

を扱えます。

JSONはWeb APIで非常によく使われるデータ形式ですが、APIそのものではありません。

MDNでも、JSONを使うREST APIの例として Content-Type: application/json が紹介されています。

参考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Type⁠(外部サイト)


バックエンドではrequestを受けてから何をしている?

フロント側からrequestを送ったあと、バックエンドでは何が起きるのでしょうか。

たとえばLaravelで、

POST /api/articles

を受けたとします。

かなり単純化すると、

routeを見つける
→ requestの値を受け取る
→ validationする
→ 認証・権限を確認する
→ 必要な処理をする
→ DBへ保存する
→ responseを返す

という流れになります。

ここで重要なのは、

APIはDBそのものではない

ということです。

APIの後ろにDBがあることは多いですが、

  • DBを使わず計算だけする

  • 外部APIを呼ぶ

  • ファイルを生成する

  • メールを送信する

  • Queueへjobを追加する

といった処理もできます。

APIは、

フロントとDBを直結するトンネル

というより、

外部から処理を依頼するためのインターフェイス

です。


responseでは「結果」と「どうなったか」が返ってくる

バックエンドで処理が終わったらresponseを返します。

たとえば記事作成が成功したなら、

HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 123,
"title": "APIって結局何?"
}

のような形です。

ここで出てくるのがstatus codeです。

HTTPのstatus codeは、requestを処理した結果を3桁の数字で表します。

RFC 9110では、大きく5クラスに分かれます。

1xx = 情報
2xx = 成功
3xx = リダイレクト
4xx = クライアント側のrequestに問題
5xx = サーバー側で処理できなかった

参考: https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes⁠(外部サイト)

よく見るものなら、

200 OK

request成功。

201 Created

requestによって新しいresourceが作成された。

400 Bad Request

request内容に問題がある。

401 Unauthorized

認証が必要、または認証に問題があるケースで使われます。

403 Forbidden

誰なのかは分かっていても、その操作を許可できない。

404 Not Found

対象resourceが見つからない。

500 Internal Server Error

サーバー側で処理中に問題が起きた。

です。

フロント側はresponseのbodyだけではなく、status codeを見て、

成功画面を出す

入力エラーを表示する

ログイン画面へ戻す

エラー表示をする

などを判断できます。

APIって結局何?フロントとバックエンドの間で何を渡してるのか、めちゃくちゃ分かりやすく整理してみた

APIの「認証」と「認可」は何をしてる?

APIで個人情報や更新処理を扱うなら、誰でも好きに呼べてはいけません。

そこで認証があります。

たとえばログイン後にtokenを持ち、

Authorization: Bearer TOKEN

としてrequestを送る。

API側でtokenを確認して、

このrequestを送ったのは誰か

を判定します。

これが認証です。

さらに、

このユーザーはこの記事を編集していいのか?

まで確認するのが認可です。

たとえば、

ログインしている = 認証OK

でも、

他人の記事を削除できる = ダメ

です。

APIを作るときは、

endpointを作ってデータが返った!

で終わらず、

誰が呼べるのか
何ができるのか

まで考える必要があります。


REST APIって結局何?

APIの説明を調べると、ほぼ必ずRESTが出てきます。

ただ、

API = REST

ではありません。

RESTはWeb APIを設計する一つのスタイルです。

HTTPのresourceやmethodなどを活かし、

GET    /articles
GET    /articles/123
POST   /articles
PATCH  /articles/123
DELETE /articles/123

のように、resourceを中心にAPIを設計する形がよく見られます。

一方でAPIには、

  • GraphQL

  • RPC系

  • WebSocketを使う仕組み

  • ブラウザ内のWeb API

  • ライブラリが提供するAPI

など、REST以外にもいろいろあります。

初心者のうちは、

APIという大きな概念の中に、HTTPを使うWeb APIがあって、その設計方法の一つとしてRESTがある

くらいで十分だと思います。


フロントからAPIを呼ぶとき、実際には何を渡している?

ここまでを一回つなげます。

たとえばフロントから、

const response = await fetch('/api/articles/123', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer TOKEN',
},
body: JSON.stringify({
title: '更新したタイトル',
}),
})

const data = await response.json()

としたとします。

このrequestでは、

endpoint

/api/articles/123

method

PATCH

headers

Content-Type: application/json
Authorization: Bearer TOKEN

body

{
"title": "更新したタイトル"
}

を送っています。

バックエンドはそれを受け取り、

誰から来たか
入力は正しいか
ID 123の記事があるか
この人が変更していいか
DBをどう更新するか

を処理します。

そして、

status code
headers
body

をresponseとして返します。

APIという言葉だけだとぼんやりしますが、実際に飛んでいるものを分解すると、それほど謎ではありません。


DevToolsのNetworkを見るとAPIが急に分かりやすくなる

APIを理解するなら、コードだけを見るよりブラウザのDevToolsにあるNetworkタブを見るのがかなり分かりやすいです。

APIを呼んだあとrequestを開くと、

  • Request URL

  • Request Method

  • Status Code

  • Request Headers

  • Response Headers

  • Payload

  • Response

などを確認できます。

つまり、この記事で説明してきたものがほぼ全部見えます。

fetchが動かない

ときも、

そもそもrequestは飛んでいる?
URLは合っている?
POSTのつもりがGETになってない?
bodyは入っている?
401なのか500なのか?
responseには何が返っている?

と追えます。

APIを「見えない裏側の何か」ではなく、

requestとresponseとして実際に観察できるもの

にすると、かなり理解しやすくなります。


APIでエラーになったら「どこまで届いたか」を見る

API周りでエラーになると、

API壊れた

でまとめたくなります。

でも実際にはいろいろあります。

request自体が飛んでいない

フロント側のJavaScriptや処理に問題がある。

endpointが違う

404になる。

認証情報がない

401などになる。

権限がない

403などになる。

validationで落ちた

400系や422など、APIの設計に応じたresponseになる。

バックエンド内部で失敗した

500系になることがある。

DBや外部サービスで失敗した

APIまでは届いているけど、その後ろで処理できていない。

なので、

フロント → API → 処理 → DB / 外部サービス → response

のどこまで進んだかを見る。

これは前にNginxを整理したときの、

ブラウザ → Nginx → アプリ

と同じ考え方です。

通信を一本道で見ると、エラーの切り分けもしやすくなります。


APIは「フロントとバックエンドをつなぐもの」だけど、それだけじゃなかった

最初の、

API = フロントとバックエンドでデータをやり取りするもの

という理解は、大きくは間違っていません。

Webアプリでは実際にその使い方をよくします。

ただ、今回整理すると、もう少し正確には、

API = ソフトウェア同士が決められたルールで機能やデータをやり取りするためのインターフェイス

です。

WebのHTTP APIなら、

endpoint = どこへ
method = 何をしてほしい
headers = 補足情報
body = 渡す中身
status code = どうなった
response body = 返ってきた結果

と分解できます。

レストランの例なら、

店を選ぶ
→ 注文窓口を選ぶ
→ 注文内容を伝える
→ 会員情報などを見せる
→ 厨房が処理する
→ 結果が返ってくる

という流れです。

少しふざけた例えですが、実際のHTTPへ戻すと全部対応しています。

APIを勉強するときは、RESTという言葉やstatus codeを一個ずつ暗記するより、

このrequestで、どこに何を渡して、何が返ってきた?

を一回追ってみる。

それだけで、フロントとバックエンドの間で起きていることがかなり見えるようになると思います。

過去の記事から 1 本

全 11 本のうち 8 本目の記事

about

このブログについて

Web 開発・インフラ・AI を手を動かして試した記録が中心です。うまくいった話もハマった話も、仕事や日々のこともそのまま書きます。