Node.js + Express入門 - REST API開発

intermediate | 60分 で読める | 2024.12.21

このチュートリアルで学ぶこと

✓ Expressプロジェクトのセットアップ
✓ ルーティングとHTTPメソッド
✓ ミドルウェアの仕組み
✓ リクエスト/レスポンス処理
✓ エラーハンドリング
✓ バリデーションとセキュリティ

前提条件

  • Node.js 18以上がインストールされていること
  • JavaScriptの基本知識

Step 1: プロジェクトセットアップ

mkdir express-api
cd express-api
npm init -y
npm install express cors helmet
npm install -D typescript @types/node @types/express ts-node nodemon

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

package.json scripts

{
  "scripts": {
    "dev": "nodemon --exec ts-node src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

Step 2: 基本的なサーバー

// src/index.ts
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';

const app = express();
const PORT = process.env.PORT || 3000;

// ミドルウェア
app.use(helmet());
app.use(cors());
app.use(express.json());

// ルート
app.get('/', (req, res) => {
  res.json({ message: 'Hello, Express!' });
});

// サーバー起動
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Step 3: ルーティング

// src/routes/users.ts
import { Router } from 'express';

const router = Router();

interface User {
  id: number;
  name: string;
  email: string;
}

let users: User[] = [
  { id: 1, name: '田中太郎', email: 'tanaka@example.com' },
  { id: 2, name: '山田花子', email: 'yamada@example.com' },
];

// 一覧取得
router.get('/', (req, res) => {
  res.json(users);
});

// 詳細取得
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }
  res.json(user);
});

// 作成
router.post('/', (req, res) => {
  const { name, email } = req.body;
  const newUser: User = {
    id: users.length + 1,
    name,
    email,
  };
  users.push(newUser);
  res.status(201).json(newUser);
});

// 更新
router.put('/:id', (req, res) => {
  const index = users.findIndex(u => u.id === parseInt(req.params.id));
  if (index === -1) {
    return res.status(404).json({ error: 'User not found' });
  }
  users[index] = { ...users[index], ...req.body };
  res.json(users[index]);
});

// 削除
router.delete('/:id', (req, res) => {
  const index = users.findIndex(u => u.id === parseInt(req.params.id));
  if (index === -1) {
    return res.status(404).json({ error: 'User not found' });
  }
  users.splice(index, 1);
  res.status(204).send();
});

export default router;

Step 4: ミドルウェア

// src/middleware/logger.ts
import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.path} ${res.statusCode} - ${duration}ms`);
  });
  next();
}

// src/middleware/auth.ts
export function authenticate(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  // トークン検証ロジック
  next();
}

Step 5: エラーハンドリング

// src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';

export class AppError extends Error {
  constructor(public statusCode: number, message: string) {
    super(message);
  }
}

export function errorHandler(
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) {
  if (err instanceof AppError) {
    return res.status(err.statusCode).json({ error: err.message });
  }
  console.error(err);
  res.status(500).json({ error: 'Internal Server Error' });
}

Step 6: アプリケーション統合

// src/index.ts
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import userRoutes from './routes/users';
import { logger } from './middleware/logger';
import { errorHandler } from './middleware/errorHandler';

const app = express();

app.use(helmet());
app.use(cors());
app.use(express.json());
app.use(logger);

app.use('/api/users', userRoutes);

app.use(errorHandler);

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

まとめ

Expressは軽量で柔軟なNode.jsフレームワークです。ミドルウェアパターンを理解し、適切なエラーハンドリングを実装することで、堅牢なAPIを構築できます。

← 一覧に戻る