web-dev-qa-db-ja.com

Node / ExpressアプリでAPIバージョンをどのように処理しますか

私はNode.jsを初めて使い、次の問題に直面しています。

私のミドルウェアはリンクapi/v1/loginおよびエンドポイントの束。その後、api/v1.1はさらに2つのエンドポイントを導入しました。 api/v1.2が最後になり、いくつかの新しいエンドポイントを取得しました。

このAPIバージョン管理を効率的な方法で処理するにはどうすればよいですか?あるバージョンのエンドポイントを次のバージョンでも使用可能にするにはどうすればよいですか?

30
Paolo.nl

まず、REST APIを構築していて、開始したばかりの場合、Expressの代わりに Restify を使用することを検討してください。Expressは確かに使用できますがこの目的のために、Restifyは、REST APIサーバー:標準化された例外、APIバージョン管理など)のすべての要件を考慮して設計されています。

したがって、最初の問題は設計上の欠陥だと思います。新しいAPIがnot以前のバージョンと下位互換性がある場合、つまりメジャーバージョンが増加する場合(v1からなど)にのみ、個別のエンドポイントを作成する必要がありますv2へ)。これは可能な限りまれに発生するはずです!
新しい機能を追加するだけ、または既存のコードを壊さない他の調整を行う場合は、別のエンドポイントを作成しないでください。したがって、v1.1、v1.2などのエンドポイントを作成しないでください。v1.0で動作するすべてのコードがv1.1でも動作することを条件に(そうでない場合は、変更を導入します。下位互換性がないため、バージョンをv2に変更することを検討する必要があります。
下位互換性のない変更を導入するたびに、すべてのユーザーがコードを更新する必要があり、すべてのユーザーが更新できるように十分な期間、古いAPIをサポートする必要があることに注意してください。これは、あなた(古いコードベースを維持する必要がある)とユーザー(彼らがコードを更新する必要がある)にとって高価なプロセスであり、可能な限り頻繁に行われるべきではありません。さらに、バージョンごとにドキュメントを作成したり、サンプルを作成したりする必要があります。
(一番下の行:APIサーバーの設計に多くの時間を費やす。可能)

質問に答えるには、各APIセット(各バージョン)のサブフォルダーを作成し、それに応じてルーターを設定します。たとえば、プロジェクトは次のようになります。

/
-- app.js
-- routes/
-- -- v1/
-- -- -- auth.js
-- -- -- list.js
-- -- v2/
-- -- -- auth.js
-- -- -- list.js

これは問題ではないはずです。v2はv1と下位互換性がないため、2つのファイルがかなり異なる可能性があります。
その後、Expressではルーターを適宜使用します。例えば:

app.get('/v1/list/:id', v1.list)
app.all('/v1/auth', v1.auth)

app.get('/v2/list/:id', v2.list)
app.all('/v2/auth', v2.auth)

ただし、他のオプションもあります。たとえば、より洗練された(わずかに高度な)ソリューションは次のとおりです。 http://j-query.blogspot.ca/2013/01/versioned-apis-with-express.html

この方法に関する注意

Semverによると、後方互換性のない変更はすべて、APIのメジャーバージョンの増加を確認する必要がありますが、v1とv2の多くの大きな違い(コードを再利用する可能性はほとんどありません)を実装する場合は、アプローチはあなたのためではありません。

この最後のケースでは、v1とv2の2つの別個のNode.jsアプリを作成し、nginxを使用して適切なルーティングを構成することができます。バージョン管理はアプリレベルでは行われません(各アプリは「/ auth」、「/ list /:id」に応答し、「/ v1/auth」、「/ v1/list:id」などには応答しません)が、nginxプレフィックス「/ v1 /」のリクエストを1つのワーカーサーバーに転送し、プレフィックス「/ v2 /」のリクエストを他のワーカーサーバーに転送します。

49
ItalyPaleAle

Restifyなどのフレームワークは、APIバージョン管理に適していますが、エクスプレスを使用しており、ルートをバージョン管理するための軽量モジュールが必要な場合は、このnpmモジュールを試してください https://www.npmjs.com/package/express-routes-バージョン管理

モジュールを使用すると、個々のルートを個別にバージョン管理できます。複数のバージョンに一致するように、サーバー上の基本的なsemverバージョンをサポートします。 (必要に応じて)。特定のバージョン管理戦略にとらわれず、アプリケーションがバージョンを設定できるようにします。

サンプルコード

var app = require('express')();
var versionRoutes = require('express-routes-versioning')();
app.listen(3000);
app.use(function(req, res, next) {
    //req.version is used to determine the version
   req.version = req.headers['accept-version'];
   next();
});
app.get('/users', versionRoutes({
   "1.0.0": respondV1,
   "~2.2.1": respondV2
}));

// curl -s -H 'accept-version: 1.0.0' localhost:3000/users
// version 1.0.0 or 1.0 or 1 !
function respondV1(req, res, next) {
   res.status(200).send('ok v1');
}

//curl -s -H 'accept-version: 2.2.0' localhost:3000/users
//Anything from 2.2.0 to 2.2.9
function respondV2(req, res, next) {
   res.status(200).send('ok v2');
}
11