LoginSignup
0
1

More than 3 years have passed since last update.

[Express] REST-API をサービス単位で管理する

Last updated at Posted at 2017-08-15

複数のサービスで共通のバックエンドを使用するという前提で、サービス単位で REST-API を管理したい、というときのメモ。
ただしバックエンドは複数のサービスとそれらが提供する REST-API を管理できるというだけで、実際に起動するときは単一のサービスのみ提供する。

つまり次のような感じ。

構成例

  • バックエンドは hogehoge, piyopiyo というサービスをサポートする
  • ただしバックエンドは実際には単一のサービスのみを提供する
  • つまり
    • hogehoge というサービスを提供する場合は piyopiyo に対する機能は提供しない
    • piyopiyo というサービスを提供する場合は hogehoge に対する機能は提供しない

この記事を実施した環境

  • Windows10 Home 64bit
  • node v8.2.1
  • npm v4.0.5
  • express v4.15.0

前提

Express のジェネレータで雛形を生成している。

バックエンドの実装

雛形生成時は routes/index.js に REST-API が直接作られている。

  • 雛形生成時の REST-API は index.js で管理
雛形生成時のindex.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

この状態でサービスごとに REST-API を作っていくと index.js がどんどん肥大化するし、本来提供しなくて良い(提供してはならない) API まで提供してしまうことになる。
これを避けるためにサービス単位で REST-API を生成するようにする。
構成としては

  1. 提供するサービスをファイルで管理(service.conf.js)
  2. サービス単位に REST-API を提供するモジュールを作る
  3. REST-API を提供するモジュールを管理する Factory を作る
  4. index.js で service.conf.js と Factory を require する

という感じで、実際のコードは次。

  • サービス単位で REST-API を管理
service.conf.js
// *******************************************
// 提供するサービスはここで管理
// *******************************************

// サービスに応じて hogehoge を変更する
module.exports = {
  'service': 'hogehoge'
};
hogehoge.js
// *******************************************
// hogehoge サービス
// *******************************************

/**
 * REST-API を作る
 *
 * @param {oject} router 'express.Router()' で生成されるオブジェクト。コール元で生成されたもの。
 */
function createApi(router) {

  /* GET home page. */
  router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express-Hogehoge' });
  });
}

/**
 * コンストラクタ
 */
const Hogehoge = function Hogehoge() {}

// prototype 継承に突っ込む
Hogehoge.prototype.createApi = createApi;

module.exports = new Hogehoge();
piyopiyo.js
// *******************************************
// piyopiyo サービス
// *******************************************

/**
 * REST-API を作る
 *
 * @param {oject} router 'express.Router()' で生成されるオブジェクト。コール元で生成されたもの。
 */
function createApi(router) {

  /* GET home page. */
  router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express-Piyopiyo' });
  });
}

/**
 * コンストラクタ
 */
const Piyopiyo = function Piyopiyo() {}

// prototype 継承に突っ込む
Piyopiyo.prototype.createApi = createApi;

module.exports = new Piyopiyo();
api-factory.js
// *******************************************
// サービスごとのモジュールを管理する Factory
// *******************************************

const hogehoge = require('./hogehoge');
const piyopiyo = require('./piyopiyo');

// サービス管理テーブル
const serviceTable = {
  'hogehoge': hogehoge,
  'piyopiyo': piyopiyo
};

/**
 * REST-API を作る
 *
 * @param {oject} router 'express.Router()' で生成されるオブジェクト。コール元で生成されたもの。
 * @param {string} service サービス名
 */
function createApi(router, service) {
  const target = serviceTable[service];
  target.createApi(router);
}

/**
 * コンストラクタ
 */
const ApiFactory = function ApiFactory() {}

// prototype 継承に突っ込む
ApiFactory.prototype.createApi = createApi;

module.exports = new ApiFactory();
index.js
const express = require('express');
const router = express.Router();
const serviceConf = require('../service.conf');
const factory = require('../app/api-factory');

// *******************************************
// Factory で REST-API を生成する
// *******************************************
factory.createApi(router, serviceConf.service);

module.exports = router;

で、これを起動させると、、、

  • srvice.conf.js に hogehoge を記載
    rest-api-hogehoge.png

  • srvice.conf.js に piyopiyo を記載
    rest-api-piyopiyo.png

と言った感じで、同じURLを叩いても違うREST-APIの結果が返ってきている。

構成

この記事で載せたプロジェクトの構成。
structure.png

課題

どうにも疎結合になっていないような気がする。
この構成だと api-factory.js は service.conf.js で設定されているサービス名を知っている必要があって、そこが気になるところ。
なんとか service.conf.js で設定されるサービス名を知らなくともサービス名を解決する手段がないものか。。。

いいアイディアが浮かんだら追記します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1