Menu
CoddyTech

バージョン管理

CoddyのNode.jsジャーニー「REST API」セクションの一部。レッスン 15/18。

応答の形式を変更すると、すでにそれを使用しているすべてのクライアントで問題が発生します。パスにバージョンを含めれば、古いクライアントと新しいクライアントを併用できます。現在は /api/v1/orders、形式を変更するときは /api/v2/orders です。移動したパスはリダイレクトで応答します。

GET  /api/orders/5   →  308  Location: /api/v1/orders/5
POST /api/orders     →  308  Location: /api/v1/orders

301 と 302 では、クライアントが POST を GET として再送することがあり、本文が失われます。308 は、メソッドと本文を含め、同じリクエストをその場所に再送するよう指示します。マウントされたミドルウェア内では、req.url からマウントパスが失われていますが、req.originalUrl にはすべて含まれています。

// GET /api/orders/5?full=1 に対する app.use('/api/orders', ...) 内では
req.url          // '/5?full=1'
req.originalUrl  // '/api/orders/5?full=1'
challenge icon

チャレンジ

簡単
  • タスクルーターを /api/v1/tasks にマウントします。
  • 古い /api/tasks パスはすべて、クエリを含め、同じパスの /api/v1 配下への 308 を返します。
  • 新しいタスクには Location: /api/v1/tasks/<id> が設定されます。

GET /api/tasks/2 を送信し、{ "title": "Order new chairs" } を指定して POST /api/tasks を送信してから、GET /api/v1/tasks/2 を送信します。

自分で試してみよう

import express from 'express';
import { sendError } from './errors.js';
import taskRoutes from './routes/tasks.js';

const BOARD_ORIGIN = 'https://board.example.com';

const app = express();
app.use(express.json());

// BOARD_ORIGIN 上のページから、ブラウザー経由でこの API を呼び出せるようにします。
app.use((req, res, next) => {
    res.set('Access-Control-Allow-Origin', BOARD_ORIGIN);
    res.set('Access-Control-Allow-Credentials', 'true');
    if (req.method === 'OPTIONS') {
        res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
        res.set('Access-Control-Allow-Headers', 'Content-Type');
        return res.status(204).end();
    }
    next();
});

app.use(express.static('public'));

app.use('/api/tasks', taskRoutes);

// ルートで発生したエラーはここで処理します。有効な JSON ではないリクエスト本文は
// クライアント側の誤り (400) で、それ以外はサーバー側の誤り (500) です。
app.use((err, req, res, next) => {
    if (err.type === 'entity.parse.failed') {
        return sendError(res, 400, 'invalid_json', 'The body is not valid JSON');
    }
    console.error(err);
    sendError(res, 500, 'server_error', 'Something went wrong');
});

app.listen(3000, () => {
    console.log('Task tracker API on port 3000');
});

REST APIのすべてのレッスン