RESTとは
REST(Representational State Transfer)は、2000年にロイ・フィリングが博士論文で提案した分散システムを構築するためのアーキテクチャスタイルです。RESTはプロトコルや標準ではなく、システムが従うべき一連の原則と制約です。
API(アプリケーションプログラミングインターフェース)は、プログラム間の相互作用のためのインターフェースです。したがって、REST APIは、RESTの原則に従って構築されたAPIです。
簡単に言うと、REST APIは、HTTPプロトコルを介してクライアントとサーバー間の通信を組織する方法であり、各リソース(データ)には一意のアドレス(URL)があり、標準のHTTPメソッドを使用してアクセスできます。
REST の基本原則
RESTは、システムアーキテクチャを定義する6つの主要な原則に基づいています。
1. クライアントサーバー
アーキテクチャは、要求を送信するクライアントと、これらの要求を処理して応答を返すサーバーに分割されます。この分割により、クライアントとサーバーは互いに独立して開発できます。
2.ステートレス(状態を保存しない)
クライアントからサーバーへの各リクエストには、リクエストを理解して処理するために必要なすべての情報が含まれている必要があります。サーバーは、要求間のクライアントの状態に関する情報を保存しません。認証が必要な場合は、要求ごとにトークンが送信されます。
3.キャッシュ可能
サーバーの応答は、キャッシュ可能かどうかを明示的に示す必要があります。これにより、サーバーへの要求数が減り、システムのパフォーマンスが向上します。
4. Uniform Interface(統一インターフェース)
これは、システムアーキテクチャを単純化するRESTの重要な原則です。これには、URI を介したリソースの識別、ビューを介したリソースの操作、自己記述メッセージ、HATEOAS(アプリケーションの状態エンジンとしてのハイパーメディア)の 4 つの側面が含まれます。
5.レイヤードシステム
クライアントは、エンドサーバーに直接接続されているのか、中間ノードに接続されているのかを判断できません。これにより、クライアントコードを変更することなく、ロードバランサー、キャッシュ、その他の中間コンポーネントを追加できます。
6. Code on Demand(コードオンデマンド)
これは唯一のオプションの原則です。サーバーは、JavaScriptなどの実行可能なコードを送信することで、クライアントの機能を一時的に拡張できます。
REST API の HTTP メソッド
REST APIは、標準のHTTPメソッドを使用してリソースの操作を実行します。各メソッドには特定の目的があります。
GET — データの取得
GETメソッドは、サーバーからデータを読み取るために使用されます。リソースの状態を変更しないでください。
// すべてのユーザーのリストを取得する
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data));
// 特定のユーザーを取得する
fetch('https://api.example.com/users/123')
.then(response => response.json())
.then(data => console.log(data));POST — 新しいリソースの作成
POSTは、サーバー上に新しいリソースを作成するために使用されます。
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Ivan Petrov',
email: 'ivan@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));PUT — リソースの完全な更新
PUTは、既存のリソースを完全に新しいデータに置き換えます。
fetch('https://api.example.com/users/123', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Ivan Petrov',
email: 'newemail@example.com',
age: 30
})
})
.then(response => response.json())
.then(data => console.log(data));PATCH — リソースの部分更新
PATCHは、リソースの指定されたフィールドのみを更新します。
fetch('https://api.example.com/users/123', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'newemail@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));DELETE — リソースの削除
DELETEは、サーバーからリソースを削除するために使用されます。
fetch('https://api.example.com/users/123', {
method: 'DELETE'
})
.then(response => {
if (response.ok) {
console.log('User removed');
}
});
REST APIの構造
REST API の正しい URL 構造は、API を理解して使用するために非常に重要です。
リソースとコレクション
RESTでは、すべてがリソースです。リソースはコレクションにグループ化されます。
GET /users - Получить список пользователей (коллекция)
GET /users/123 - Получить конкретного пользователя (ресурс)
POST /users - Создать нового пользователя
PUT /users/123 - Обновить пользователя
DELETE /users/123 - Удалить пользователя埋め込みリソース
関連するリソースには、ネストされたURLが使用されます。
GET /users/123/posts - Все посты пользователя
GET /users/123/posts/456 - Конкретный пост пользователя
POST /users/123/posts - Создать пост для пользователя
DELETE /users/123/posts/456 - Удалить пост пользователяフィルタリングと並べ替え
フィルタリング、並べ替え、ページネーションにはクエリパラメータを使用します。
GET /users?role=admin - Фильтрация по роли
GET /users?sort=name&order=asc - Сортировка по имени
GET /users?page=2&limit=20 - Пагинация
GET /users?search=иван - Поиск応答のHTTPステータス
REST APIは、標準のHTTPステータスコードを使用して、クライアントに要求の結果を通知します。
成功した応答(2xx)
200 OK — リクエストが正常に完了しました(GET、PUT、PATCHの場合)
201 Created — リソースが正常に作成されました (POST の場合)
204 No Content — リクエストは正常に完了しましたが、返すコンテンツがありません(多くの場合、DELETEの場合)
クライアントエラー(4xx)
400 Bad Request — 正しくないリクエスト(例:無効なJSON)
401 Unauthorized — 認証が必要です
403 Forbidden — アクセスが拒否されました(認証されていますが、権限がありません)
404 Not Found — リソースが見つかりません
409 Conflict — 競合(たとえば、このメールアドレスを持つユーザーがすでに存在する)
422 Unprocessable Entity — 検証に失敗しました
サーバーエラー(5xx)
500 Internal Server Error — 内部サーバーエラー
503 Service Unavailable — サービスは一時的に利用できません
データ形式
REST APIは通常、JSON(JavaScript Object Notation)で動作しますが、XMLを使用することもできます。
JSON 応答の例
{
"id": 123,
"name": "Ivan Petrov",
"email": "ivan@example.com",
"created_at": "2024-01-15T10:30:00Z",
"posts": [
{
"id": 1,
"title": "First post",
"published": true
}
]
}JSONエラーの例
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Data validation error",
"details": [
{
"field": "email",
"message": "Incorrect email format"
}
]
}
}認証とセキュリティ
REST API では、保護されたリソースにアクセスするために認証が必要になることがよくあります。
JWT (JSON Web Token)
REST APIの最も一般的な認証方法:
// ログイン時にトークンを取得する
fetch('https://api.example.com/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'user@example.com',
password: 'password123'
})
})
.then(response => response.json())
.then(data => {
// トークンを保存しています
localStorage.setItem('token', data.token);
});
// 保護されたリクエストにトークンを使用する
fetch('https://api.example.com/users/me', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
})
.then(response => response.json())
.then(data => console.log(data));API Keys
サービス指向APIのシンプルな方法:
fetch('https://api.example.com/data', {
headers: {
'X-API-Key': 'your-secret-key'
}
})
.then(response => response.json())
.then(data => console.log(data));APIのバージョン管理
API が開発されるにつれて、下位互換性を維持することが重要です。バージョン管理にはいくつかのアプローチがあります。
URL Path Versioning
https://api.example.com/v1/users
https://api.example.com/v2/usersHeader Versioning
fetch('https://api.example.com/users', {
headers: {
'Accept': 'application/vnd.example.v2+json'
}
})Query Parameter Versioning
https://api.example.com/users?version=2
実例:Node.jsでシンプルなREST APIを作成する
タスクリストを管理するためのシンプルなREST APIを作成しましょう。
const express = require('express');
const app = express();
app.use(express.json());
// 一時的なデータストレージ
let tasks = [
{ id: 1, title: 'Explore the REST API', completed: false },
{ id: 2, title: 'Create a project', completed: false }
];
let nextId = 3;
// GET - すべてのタスクを取得する
app.get('/api/tasks', (req, res) => {
res.json(tasks);
});
// GET - 特定のタスクを取得する
app.get('/api/tasks/:id', (req, res) => {
const task = tasks.find(t => t.id === parseInt(req.params.id));
if (!task) {
return res.status(404).json({
error: 'Task not found'
});
}
res.json(task);
});
// POST - 新しいタスクを作成する
app.post('/api/tasks', (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
error: 'Task name is required'
});
}
const newTask = {
id: nextId++,
title,
completed: false
};
tasks.push(newTask);
res.status(201).json(newTask);
});
// PUT - タスクを更新する
app.put('/api/tasks/:id', (req, res) => {
const taskIndex = tasks.findIndex(t => t.id === parseInt(req.params.id));
if (taskIndex === -1) {
return res.status(404).json({
error: 'Task not found'
});
}
const { title, completed } = req.body;
tasks[taskIndex] = {
id: parseInt(req.params.id),
title: title || tasks[taskIndex].title,
completed: completed !== undefined ? completed : tasks[taskIndex].completed
};
res.json(tasks[taskIndex]);
});
// DELETE - タスクを削除する
app.delete('/api/tasks/:id', (req, res) => {
const taskIndex = tasks.findIndex(t => t.id === parseInt(req.params.id));
if (taskIndex === -1) {
return res.status(404).json({
error: 'Task not found'
});
}
tasks.splice(taskIndex, 1);
res.status(204).send();
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});REST API開発のベストプラクティス
1. 動詞ではなく名詞を使用する
良い:
GET /users
POST /users悪い点:
GET /getUsers
POST /createUser2.コレクションには複数形を使用する
GET /users (а не /user)
GET /posts (а не /post)3.正しいHTTPコードを返す
すべての応答に対して200 OKを返さないでください。適切な状態コードを使用してください。
4. 詳細なエラーメッセージを提供する
{
"error": {
"code": "INVALID_EMAIL",
"message": "Invalid email address provided",
"field": "email",
"value": "invalid-email"
}
}5. 大規模なコレクションにはページネーションを使用する
app.get('/api/users', (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const results = {
data: users.slice(startIndex, endIndex),
pagination: {
page,
limit,
total: users.length,
totalPages: Math.ceil(users.length / limit)
}
};
res.json(results);
});6. API を文書化する
API を文書化するには、Swagger/OpenAPI などのツールを使用します。
7. HTTPSを使用する
特に機密情報を扱う場合は、データ転送に常にHTTPSを使用してください。
8. レート制限を実装する
悪用を防ぐために、1 人のクライアントからのリクエスト数を制限します。
REST vs GraphQL vs gRPC
REST は API を構築する唯一の方法ではありません。以下に簡単な比較を示します。
REST ほとんどの標準的なWebアプリケーションに適しており、理解しやすく実装しやすく、幅広いサポートと優れたキャッシュ機能を備えています。
GraphQL クライアントがデータの選択に柔軟性を必要とする場合に役立ちます。1回のクエリですべてを取得し、データのオーバーフェッチまたはアンダーフェッチを回避できます。
gRPC マイクロサービスアーキテクチャ、高性能システム、内部APIに最適で、バイナリプロトコルを使用し、RESTよりも高速です。
REST API を操作するためのツール
APIテスト
Postman —グラフィカルインターフェイスを備えた人気のAPIテストツール
Insomnia — ミニマリストなインターフェースを備えたPostmanの代替手段
curl — HTTPリクエスト用のコンソールユーティリティ
# curlの使用例
curl -X GET https://api.example.com/users
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name":"Ivan","email":"ivan@example.com"}'クライアントライブラリ
JavaScript/TypeScript:
Fetch API (組み込み)
Axios
Got
Python:
requests
httpx
PHP:
Guzzle
cURL
結論
REST APIは、クライアントとサーバー間の通信にシンプルで標準化された方法を提供する、現代のWeb開発の基本技術です。RESTの原則を理解し、HTTPメソッドとステータスコードを正しく使用し、ベストプラクティスに従うことで、高品質でスケーラブルでメンテナンスしやすいAPIを作成できます。
シンプルなプロジェクトから始めて、徐々に複雑さを加えて、ドキュメントとテストを忘れないでください。REST APIは、長年にわたって関連性を維持し、現代の開発の世界への扉を開くスキルです。
教育プラットフォームに参加する コディックJavaScript、Node.js、Python、その他の最新テクノロジーに関する構造化されたコースが見つかります。
当社のフレンドリーな開発者コミュニティ Telegram プログラマーになるための質問、経験の共有、サポートをいつでもお手伝いします!
