APIについて

# APIについて

## 1. APIとは

APIとは、_Application Programming Interface(アプリケーション・プログラミング・インターフェース)_の略称であり、**ソフトウェア同士がやりとりするための「窓口」や「約束事」**のこと。<br>
APIを使用することで、既存のアプリケーションの機能やデータを簡単に取り扱うことができ、開発を簡略化することができる。

:::note info
「窓口」とは、ソフトウェアがデータや機能を呼び出すためにアクセスする入り口やインターフェースのこと。
:::

:::note info 
「約束事」とは、ソフトウェア同士が円滑にやり取りを行うために定められたルールや仕様のこと。
:::

## 2. エンドポイントとは

エンドポイントとは、ソフトウェアが外部の機能やデータにアクセスするときの入口となる場所や、URLのこと。つまり、**どのURLやパスを使えば、その機能にアクセスできるかを示したもの**である。

## 3. HTTPリクエストとHTTPレスポンスとは

HTTPリクエストとは、クライアント（ブラウザやアプリケーション）がサーバーに対して何かを要求する時に送るメッセージ。
***
HTTPレスポンスとは、主にサーバーがクライアントのリクエストに対して返信するメッセージ。

:::note info
HTTPとは、_Hypertext Transfer Protocol＿の略称で、ウェブブラウザとウェブサーバーがウェブページのデータをやり取りする際に使う**プロトコル**（通信ルール）。
:::

## 4. HTTPメソッドとは

HTTPリクエストを送る際の**命令の種類**のこと。

:::note info
代表的なメソッド
* GET
* POST
* PUT
* PATCH
* DELETE
* HEAD
:::

# 5. CORS（Cross-Origin Resource Sharing）とは？

CORS（クロスオリジンリソース共有）は、**異なるドメイン間でのリソースのやり取りを制御する仕組み**のこと。

## 1. そもそも「オリジン」とは？
「オリジン（Origin）」とは、**プロトコル（http/https）、ドメイン、ポート**の3つの組み合わせ。

例えば：
- `http://example.com:80` （プロトコル: `http`, ドメイン: `example.com`, ポート: `80`）
- `https://example.com:443` （プロトコルが `https` なので、別のオリジン）
- `http://api.example.com:80` （サブドメインが異なるので、別のオリジン）

## 2. なぜCORSが必要なのか？
セキュリティの観点から、**ブラウザは「異なるオリジンのリクエスト」を基本的にブロックする仕様（SOP: Same-Origin Policy）** になっている。

例えば、あるウェブサイト（`http://frontend.com`）が、別のサーバー（`http://api.backend.com`）のデータを取得しようとすると、ブラウザは **「これは危険かもしれない！」** と判断し、ブロックしてしまう。
これを回避するために **CORS** という仕組みがあり、サーバー側で「このドメインからのアクセスは許可するよ」と設定できる。

## 3. CORSの仕組み
サーバー側で `Access-Control-Allow-Origin` というヘッダーを設定することで、特定のオリジンからのリクエストを許可できる。

# 6. RESTとは？
**REST（Representational State Transfer）** とは、Web API を設計するための有名な設計思想のこと。  
REST の考え方に沿って設計された API を **REST API** と呼ぶ。

REST の特徴：
- **シンプルな構造** で設計しやすい
- **HTTPメソッド（GET, POST, PUT, DELETE）を活用** する
- **リソース（データ）に対して適切なURLを設計** する

例えば、ユーザー情報を取得する API を考えると：
GET /users/1 → ユーザーID 1 の情報を取得
のような形になる。

---

## 2. RESTの4つの原則
REST には **4つの重要な原則** があり、これを守ることで分かりやすく設計しやすい API になる。

### ✅ ① **リソース指向（リソースを識別する）**
**API の URL は「何のデータ（リソース）を扱うか」に基づいて設計** する。
例えば、ユーザー情報を扱う API なら、以下のように設計。

| 操作内容 | HTTPメソッド | エンドポイント |
|---------|-------------|---------------|
| ユーザー一覧を取得 | `GET` | `/users` |
| ユーザーID 1の情報を取得 | `GET` | `/users/1` |
| 新しいユーザーを作成 | `POST` | `/users` |
| ユーザーID 1の情報を更新 | `PUT` | `/users/1` |
| ユーザーID 1を削除 | `DELETE` | `/users/1` |

**❌ NGな例**
GET /getUser?id=1 （動作はするが、RESTでは推奨されない）
**✅ 正しい例**
GET /users/1 （リソース指向の設計）


---

### ✅ ② **ステートレス（状態を持たない）**
**サーバー側でユーザーの状態（ログイン情報など）を記憶しない** 設計にする。  
リクエストごとに、必要な情報（認証トークンなど）を送ることで、一貫性のある設計ができる。

**❌ NGな例**
ログイン後、サーバーがユーザーのセッションを保持して動作するAPI
**✅ 正しい例**
全てのリクエストで Authorization ヘッダーにトークンを含める
GET /users/1
Authorization: Bearer <アクセストークン>


### ✅ ③ **統一されたインターフェース**
**すべてのAPIで一貫したルールを守る** ことで、開発者がAPIを理解しやすくする。

#### **ポイント**
- **HTTPメソッドを適切に使う**
  - `GET`：データ取得
  - `POST`：新規作成
  - `PUT`：更新
  - `DELETE`：削除
- **レスポンスはJSON形式で統一**
  - ✅ **正しい例**
    ```json
    {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com"
    }
    ```
  - ❌ **NGな例（HTMLを返す）**
    ```html
    <html>
      <body>User not found</body>
    </html>
    ```
- **エラーメッセージも統一**
  - ✅ **正しい例**
    ```json
    {
      "error": "ユーザーが見つかりません"
    }
    ```
  - ❌ **NGな例（エラーメッセージがバラバラ）**
    - `User not found`
    - `ユーザーが存在しません`
    - `エラー 404: ユーザーがいません`

**統一したインターフェースを設計することで、APIの利用が簡単になり、開発の効率が向上。**

---

### ✅ ④ **クライアントとサーバーの分離**
**フロントエンド（クライアント）とバックエンド（サーバー）は独立** しているべき。  
API の変更がフロントエンドに影響を与えないように設計する。

#### **クライアントとサーバーの役割**
| 役割 | 具体例 |
|------|------|
| クライアント | ユーザーが操作するUIを提供（React, Vue.js, Angularなど） |
| サーバー | データ処理・APIの提供（Django, Node.js, FastAPIなど） |

#### **メリット**
✅ **フロントとバックを別々に開発できる**
- 例: React（フロント）と Django（バックエンド）を並行して開発可能

✅ **バックエンドを変更してもフロントエンドに影響が少ない**
- APIの仕様を維持すれば、フロントのコードを大きく変えなくても済む

✅ **異なるデバイスやアプリからのアクセスが可能**
- Webアプリ、モバイルアプリ、デスクトップアプリ など、どこからでも同じAPIを使える

#### **例**
1. クライアント（React）が `GET /users/1


# 7. **JWT 認証とは？**

## 1. 認証とは？
認証（Authentication）とは、**「ユーザーが本人であることを確認する仕組み」**。

認証が成功すると、サーバーは「このユーザーは信頼できる」と判断し、リソースへのアクセスを許可する。

---

## 2. 認証の方法
認証には様々な方法がありますが、有名なものを **3つ** 紹介。

### **① セッション認証**
**仕組み**
1. ユーザーがログイン（ID・パスワードを送信）
2. サーバーがユーザー情報を確認し、セッションIDを発行
3. クライアントはこのセッションIDをCookieに保存し、リクエストごとに送信
4. サーバーはセッションIDをチェックし、ユーザーを識別

**メリット**
✅ サーバー側で管理するため、セキュリティが高い  
✅ ログアウト処理が簡単

**デメリット**
❌ スケーラビリティが低い（サーバーごとにセッション情報を管理する必要がある）  
❌ マルチデバイスでのログイン管理が難しい

---

### **② OAuth（オーオース）**
**仕組み**
- GoogleやFacebookのログイン機能（「Googleでログイン」ボタンなど）
- OAuthサーバーが認証を担当し、アクセストークンを発行

**メリット**
✅ ユーザーはパスワードを入力しなくても認証できる  
✅ サービスごとに異なる認証情報を使えるため、安全性が高い

**デメリット**
❌ 外部サービス（Googleなど）に依存する  
❌ 実装がやや複雑

---

### **③ JWT（JSON Web Token）認証**
**仕組み**
1. ユーザーがログイン（ID・パスワードを送信）
2. サーバーがユーザー情報を確認し、JWTを発行
3. クライアントはJWTを保存し、リクエストごとに送信
4. サーバーはJWTの署名を確認し、ユーザーを識別

**メリット**
✅ **トークンだけで認証可能**（サーバーでセッションを管理しなくてよい）  
✅ **スケーラビリティが高い**（マイクロサービスでも利用しやすい）  

**デメリット**
❌ トークンの無効化が難しい（ログアウトしてもトークンが有効なままの可能性がある）  
❌ トークンのサイズが大きい（ヘッダー＋ペイロード＋署名を含む）

---

## 3. JWTとは？
**JWT（JSON Web Token）** とは、API の認証によく使われる **データのやり取りフォーマット**。

JWTの特徴：
- **トークンベースの認証**（セッション不要）
- **自己完結型**（ユーザー情報をトークン内に保持）
- **改ざん防止のための署名（HS256, RS256など）**

JWTは **3つの部分** から構成される：
ヘッダー.ペイロード.署名

## 4. JWT認証の流れ
以下は、JWTを用いた認証の流れ。

### **(1) ユーザーがログイン**
- ユーザーが `email` と `password` を送信
- サーバーが認証を行う

### **(2) サーバーがJWTを発行**
- 認証に成功したら、JWT（トークン）を発行
- クライアント側にトークンを返す

### **(3) クライアントがトークンを保存**
- クライアントは JWT を **localStorage** や **Cookie** に保存

### **(4) APIリクエスト時にJWTを送信**
- クライアントはAPIを呼び出す際、JWTを **`Authorization` ヘッダー** に含めて送信

Authorization: Bearer <JWTトークン>


### **(5) サーバーがトークンを検証**
- 受け取ったトークンの **署名を検証** し、正しいユーザーかチェック

### **(6) 認証成功なら、リソースにアクセス**
- 検証に成功すれば、APIがリクエストを処理し、データを返す

## JWT認証のシーケンス図
[クライアント] --(1) ログイン情報を送信 --> [サーバー]
[サーバー] --(2) JWTトークンを発行 --> [クライアント]
[クライアント] --(3) JWTを保存 --> [ローカルストレージ or Cookie]
[クライアント] --(4) JWTをヘッダーに含めてAPIリクエスト --> [サーバー]
[サーバー] --(5) JWTを検証 --> [認証成功]
[サーバー] --(6) データを返す --> [クライアント]


## 5. JWT認証のメリット・デメリット

JWTには利点と欠点があるため、用途に応じて適切に選択。

### **✅ メリット**
| 項目 | 内容 |
|------|------|
| **スケーラビリティ** | セッションをサーバー側で管理しないため、スケールしやすい（複数のサーバーで負荷分散しやすい）。 |
| **パフォーマンス** | 各リクエストでデータベースを問い合わせる必要がなく、高速な認証が可能。 |
| **セキュリティ** | 署名付きのため、データの改ざんを防ぐことができる。 |
| **マルチプラットフォーム対応** | フロントエンド（React, Vue, Angular）やモバイルアプリ（iOS, Android）でも簡単に利用可能。 |

### **⚠️ デメリット**
| 項目 | 内容 |
|------|------|
| **トークンの無効化が難しい** | JWTは自己完結型のため、一度発行したトークンを無効化するのが困難（例: ユーザーがログアウトしても、トークンの有効期限が切れるまで使えてしまう）。 |
| **セキュリティリスク** | トークンが漏洩すると、攻撃者がAPIを自由に利用できてしまうため、適切な管理が必要（例: HTTPSを使用する、短い有効期限を設定する）。 |
| **トークンのサイズが大きい** | JWTにはヘッダー・ペイロード・署名が含まれるため、セッションIDと比べるとデータ量が増加し、通信コストがやや高い。 |
| **リフレッシュトークンの管理が必要** | アクセストークンの有効期限が短いため、新しいトークンを発行する仕組み（リフレッシュトークン）が必要になる。 |

---

### **🔍 まとめ**
| 項目 | 内容 |
|------|------|
| **メリット** | 高速・スケーラブルで、様々なプラットフォームで利用しやすい。 |
| **デメリット** | 無効化が難しく、適切なセキュリティ対策が必要。 |

JWTを使用する際は、**短い有効期限 + リフレッシュトークン + HTTPS通信** を活用し、安全な認証システムを構築を意識する。