【初心者向け】Express.jsでREST API設計をマスターしよう!ネストされたルーターでコードをスッキリ整理
Express.js でネストされたルーターを使用した REST API 設計
Express.js は、Node.js 向けの軽量で柔軟な Web アプリケーションフレームワークです。REST API を設計する際に、ネストされたルーターを使用してコードをモジュール化し、整理することができます。
利点
- コードの可読性と保守性を向上
- ルーティングの複雑さを軽減
- 再利用可能なコードの作成
- 関連するルートを論理的にグループ化
例
以下の例は、ユーザーと投稿を管理する REST API をネストされたルーターを使用して設計する方法を示しています。
const express = require('express');
const app = express();
const userRouter = express.Router();
const postRouter = express.Router();
// ユーザー関連のルート
userRouter.get('/', (req, res) => {
// ユーザー一覧を取得
});
userRouter.get('/:userId', (req, res) => {
// 特定のユーザーを取得
});
userRouter.post('/', (req, res) => {
// 新しいユーザーを作成
});
userRouter.put('/:userId', (req, res) => {
// ユーザーを更新
});
userRouter.delete('/:userId', (req, res) => {
// ユーザーを削除
});
// 投稿関連のルート
postRouter.get('/', (req, res) => {
// 投稿一覧を取得
});
postRouter.get('/:postId', (req, res) => {
// 特定の投稿を取得
});
postRouter.post('/', (req, res) => {
// 新しい投稿を作成
});
postRouter.put('/:postId', (req, res) => {
// 投稿を更新
});
postRouter.delete('/:postId', (req, res) => {
// 投稿を削除
});
// ルーターのマウント
app.use('/users', userRouter);
app.use('/posts', postRouter);
app.listen(3000, () => {
console.log('Server started on port 3000');
});
ポイント
express.Router()
を使用して、ネストされたルーターを作成します。- ルーターごとに関連するルートをグループ化します。
- 各ルートには、適切な HTTP メソッド (GET、POST、PUT、DELETE) を割り当てます。
app.use()
メソッドを使用して、ネストされたルーターをメインアプリケーションにマウントします。
Express.js のネストされたルーターは、REST API を設計する際に役立つ強力なツールです。コードをモジュール化し、整理することで、可読性と保守性を向上させることができます。
- 上記の例はあくまで基本的な例です。実際のアプリケーションでは、より複雑なルーティングやロジックが必要になる場合があります。
- エラー処理や認証などの機能を追加する必要があります。
この例では、以下のファイル構成を使用します。
app.js
: メインアプリケーションファイルuserRouter.js
: ユーザー関連のルートを定義するファイル
コード解説
app.js
const express = require('express');
const app = express();
const userRouter = require('./userRouter');
const postRouter = require('./postRouter');
// ルーターのマウント
app.use('/users', userRouter);
app.use('/posts', postRouter);
app.listen(3000, () => {
console.log('Server started on port 3000');
});
- このファイルは、メインアプリケーションのセットアップと、ユーザーと投稿のルーターのマウントを行います。
userRouter.js
const express = require('express');
const userRouter = express.Router();
// ユーザー一覧を取得
userRouter.get('/', (req, res) => {
// データベースからユーザー一覧を取得
// ...
res.json({
users: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
],
});
});
// 特定のユーザーを取得
userRouter.get('/:userId', (req, res) => {
const userId = parseInt(req.params.userId);
// データベースから特定のユーザーを取得
// ...
const user = { id: 1, name: 'John Doe' };
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json({ user });
});
// 新しいユーザーを作成
userRouter.post('/', (req, res) => {
const { name } = req.body;
// データベースに新しいユーザーを作成
// ...
const user = { id: 3, name };
res.status(201).json({ user });
});
// ユーザーを更新
userRouter.put('/:userId', (req, res) => {
const userId = parseInt(req.params.userId);
const { name } = req.body;
// データベースのユーザーを更新
// ...
const user = { id: userId, name };
res.json({ user });
});
// ユーザーを削除
userRouter.delete('/:userId', (req, res) => {
const userId = parseInt(req.params.userId);
// データベースからユーザーを削除
// ...
res.status(204).send();
});
module.exports = userRouter;
- このファイルは、ユーザー関連のルートを定義します。
module.exports
を使用して、ルーターをエクスポートします。
const express = require('express');
const postRouter = express.Router();
// 投稿一覧を取得
postRouter.get('/', (req, res) => {
// データベースから投稿一覧を取得
// ...
res.json({
posts: [
{ id: 1, title: 'My first post', content: 'This is my first post.' },
{ id: 2, title: 'Another post', content: 'This is another post.' },
],
});
});
// 特定の投稿を取得
postRouter.get('/:postId', (req, res) => {
const postId = parseInt(req.params.postId);
// データベースから特定の投稿を取得
// ...
const post = { id: 1, title: 'My first post', content: 'This is my first post.' };
if (!post) {
return res.status(404).json({ message
すべてのリソースを単一のレベルのルーターで定義する方法です。
app.get('/users', (req, res) => {
// ...
});
app.get('/users/:userId', (req, res) => {
// ...
});
app.post('/users', (req, res) => {
// ...
});
app.put('/users/:userId', (req, res) => {
// ...
});
app.delete('/users/:userId', (req, res) => {
// ...
});
app.get('/posts', (req, res) => {
// ...
});
app.get('/posts/:postId', (req, res) => {
// ...
});
app.post('/posts', (req, res) => {
// ...
});
app.put('/posts/:postId', (req, res) => {
// ...
});
app.delete('/posts/:postId', (req, res) => {
// ...
});
- シンプルで理解しやすい
- ネストが必要ない場合に適している
短所
- コードが冗長になる可能性がある
- 多くのリソースがある場合、管理が難しくなる
ファイルベースのルーティング
各リソースタイプ用の個別のファイルでルートを定義する方法です。
// users.js
app.get('/users', require('./controllers/users/get'));
app.get('/users/:userId', require('./controllers/users/get'));
app.post('/users', require('./controllers/users/post'));
app.put('/users/:userId', require('./controllers/users/put'));
app.delete('/users/:userId', require('./controllers/users/delete'));
// posts.js
app.get('/posts', require('./controllers/posts/get'));
app.get('/posts/:postId', require('./controllers/posts/get'));
app.post('/posts', require('./controllers/posts/post'));
app.put('/posts/:postId', require('./controllers/posts/put'));
app.delete('/posts/:postId', require('./controllers/posts/delete'));
- コードをモジュール化しやすい
- 設定が複雑になる可能性がある
- ファイルシステムの階層構造が深くなりすぎると、探しにくくなる
フレームワーク
REST API 設計専用のフレームワークを使用する方法です。
- ルーティング、認証、エラー処理などの機能を簡素化
- ベストプラクティスに基づいた設計を促進
- 習得曲線が上がる
- Express.js のような柔軟性がない場合がある
最適な方法を選択
最適な方法は、要件によって異なります。
- 小規模な API でシンプルなルーティング構造の場合は、単一レベルのルーター が適しています。
- 中規模から大規模な API で、コードをモジュール化したい場合は、ファイルベースのルーティング または フレームワーク が適しています。
- 複雑な API で、ベストプラクティスに基づいた設計をしたい場合は、フレームワーク が適しています。
- バージョン管理: API のバージョンを管理する必要がある場合は、バージョン番号をルーティングに含めることができます。
- 認証: API を保護する必要がある場合は、認証ミドルウェアを使用する必要があります。
- エラー処理: エラーが発生した場合に、適切なエラーメッセージを返せるようにする必要があります。
- ドキュメント: API ドキュメントを生成して、開発者が API を簡単に理解できるようにする必要があります。
javascript node.js express