diff --git a/lib/app.js b/lib/app.js index c1b30f941c..9ed9fbafea 100644 --- a/lib/app.js +++ b/lib/app.js @@ -49,11 +49,7 @@ module.exports = function(config) { } // Setup API routes - const middleware = new IndexRouter(config); - if (!middleware) { - throw new Error('Routes invalid'); - } - app.use(`${baseUriPath}/`, middleware.router()); + app.use(`${baseUriPath}/`, new IndexRouter(config).router); if (process.env.NODE_ENV !== 'production') { app.use(errorHandler()); diff --git a/lib/routes/admin-api/feature.test.js b/lib/routes/admin-api/feature.test.js index dd08b7687e..4c807896a6 100644 --- a/lib/routes/admin-api/feature.test.js +++ b/lib/routes/admin-api/feature.test.js @@ -201,6 +201,7 @@ test('invalid feature names should not pass validation', t => { ); }); +// Make sure current UI works. Should align on joi errors in future. test('invalid feature names should have error msg', t => { t.plan(1); const { request, base } = getSetup(); diff --git a/lib/routes/admin-api/index.js b/lib/routes/admin-api/index.js index 912e0ca869..8cac3f2812 100644 --- a/lib/routes/admin-api/index.js +++ b/lib/routes/admin-api/index.js @@ -16,10 +16,10 @@ class AdminApi extends Controller { const stores = config.stores; this.app.get('/', this.index); - this.app.use('/features', new FeatureController(stores).router()); - this.app.use('/archive', new ArchiveController(stores).router()); + this.app.use('/features', new FeatureController(stores).router); + this.app.use('/archive', new ArchiveController(stores).router); this.app.use('/strategies', strategies.router(config)); - this.app.use('/events', new EventController(stores).router()); + this.app.use('/events', new EventController(stores).router); this.app.use('/metrics', metrics.router(config)); this.app.use('/user', user.router(config)); } diff --git a/lib/routes/backstage.js b/lib/routes/backstage.js index 39d7cd5182..cc91d06072 100644 --- a/lib/routes/backstage.js +++ b/lib/routes/backstage.js @@ -1,24 +1,18 @@ 'use strict'; -const { Router } = require('express'); const { register: prometheusRegister } = require('prom-client'); +const Controller = require('./controller'); -class BackstageController { +class BackstageController extends Controller { constructor(config) { - const router = Router(); + super(); if (config.serverMetrics) { - router.get('/prometheus', (req, res) => { + this.get('/prometheus', (req, res) => { res.set('Content-Type', prometheusRegister.contentType); res.end(prometheusRegister.metrics()); }); } - - this.app = router; - } - - router() { - return this.app; } } diff --git a/lib/routes/client-api/feature.js b/lib/routes/client-api/feature.js index 5a3b0106ab..1b777097d0 100644 --- a/lib/routes/client-api/feature.js +++ b/lib/routes/client-api/feature.js @@ -1,18 +1,17 @@ 'use strict'; -const { Router } = require('express'); +const Controller = require('../controller'); const { filter } = require('./util'); const version = 1; -class FeatureController { +class FeatureController extends Controller { constructor({ featureToggleStore }) { - const router = Router(); - this._router = router; + super(); this.toggleStore = featureToggleStore; - router.get('/', (req, res) => this.getAll(req, res)); - router.get('/:featureName', this.getFeatureToggle.bind(this)); + this.get('/', this.getAll); + this.get('/:featureName', this.getFeatureToggle); } async getAll(req, res) { @@ -33,10 +32,6 @@ class FeatureController { res.status(404).json({ error: 'Could not find feature' }); } } - - router() { - return this._router; - } } module.exports = FeatureController; diff --git a/lib/routes/client-api/index.js b/lib/routes/client-api/index.js index 1b516cddc7..80f7458990 100644 --- a/lib/routes/client-api/index.js +++ b/lib/routes/client-api/index.js @@ -1,31 +1,26 @@ 'use strict'; -const { Router } = require('express'); +const Controller = require('../controller'); const FeatureController = require('./feature.js'); const MetricsController = require('./metrics.js'); const RegisterController = require('./register.js'); const apiDef = require('./api-def.json'); -class ClientApi { +class ClientApi extends Controller { constructor(config) { - const router = Router(); - this._router = router; + super(); const stores = config.stores; - router.get('/', this.index); - router.use('/features', new FeatureController(stores).router()); - router.use('/metrics', new MetricsController(stores).router()); - router.use('/register', new RegisterController(stores).router()); + this.get('/', this.index); + this.use('/features', new FeatureController(stores).router); + this.use('/metrics', new MetricsController(stores).router); + this.use('/register', new RegisterController(stores).router); } index(req, res) { res.json(apiDef); } - - router() { - return this._router; - } } module.exports = ClientApi; diff --git a/lib/routes/client-api/metrics.js b/lib/routes/client-api/metrics.js index 74d109b644..bdd128bd14 100644 --- a/lib/routes/client-api/metrics.js +++ b/lib/routes/client-api/metrics.js @@ -1,19 +1,18 @@ 'use strict'; -const { Router } = require('express'); const joi = require('joi'); const logger = require('../../logger')('client-api/metrics.js'); +const Controller = require('../controller'); const { clientMetricsSchema } = require('./metrics-schema'); -class ClientMetricsController { +class ClientMetricsController extends Controller { constructor({ clientMetricsStore, clientInstanceStore }) { - const router = Router(); + super(); this.clientMetricsStore = clientMetricsStore; this.clientInstanceStore = clientInstanceStore; - this._router = router; - router.post('/', (req, res) => this.registerMetrics(req, res)); + this.post('/', this.registerMetrics); } async registerMetrics(req, res) { @@ -40,10 +39,6 @@ class ClientMetricsController { res.status(500).end(); } } - - router() { - return this._router; - } } module.exports = ClientMetricsController; diff --git a/lib/routes/client-api/register.js b/lib/routes/client-api/register.js index 6223dbbbee..5595a936ad 100644 --- a/lib/routes/client-api/register.js +++ b/lib/routes/client-api/register.js @@ -1,19 +1,18 @@ 'use strict'; -const { Router } = require('express'); const joi = require('joi'); const logger = require('../../logger')('/client-api/register.js'); +const Controller = require('../controller'); const { clientRegisterSchema: schema } = require('./register-schema'); -class RegisterController { +class RegisterController extends Controller { constructor({ clientInstanceStore, clientApplicationsStore }) { - const router = Router(); - this._router = router; + super(); this.clientInstanceStore = clientInstanceStore; this.clientApplicationsStore = clientApplicationsStore; - router.post('/', (req, res) => this.handleRegister(req, res)); + this.post('/', this.handleRegister); } async handleRegister(req, res) { @@ -41,10 +40,6 @@ class RegisterController { return res.status(500).end(); } } - - router() { - return this._router; - } } module.exports = RegisterController; diff --git a/lib/routes/controller.js b/lib/routes/controller.js index 8c95a51bda..8ef578dc9c 100644 --- a/lib/routes/controller.js +++ b/lib/routes/controller.js @@ -26,7 +26,11 @@ class Controller { this.app.delete(path, handler.bind(this)); } - router() { + use(path, router) { + this.app.use(path, router); + } + + get router() { return this.app; } } diff --git a/lib/routes/health-check.js b/lib/routes/health-check.js index 241e09903e..9d5871a1cc 100644 --- a/lib/routes/health-check.js +++ b/lib/routes/health-check.js @@ -1,16 +1,14 @@ 'use strict'; -const { Router } = require('express'); const logger = require('../logger')('health-check.js'); +const Controller = require('./controller'); -class HealthCheckController { +class HealthCheckController extends Controller { constructor(config) { - const app = Router(); - - this.app = app; + super(); this.db = config.stores.db; - app.get('/', (req, res) => this.index(req, res)); + this.get('/', (req, res) => this.index(req, res)); } async index(req, res) { @@ -22,10 +20,6 @@ class HealthCheckController { res.status(500).json({ health: 'BAD' }); } } - - router() { - return this.app; - } } module.exports = HealthCheckController; diff --git a/lib/routes/index.js b/lib/routes/index.js index b00095e0af..91600e4db2 100644 --- a/lib/routes/index.js +++ b/lib/routes/index.js @@ -1,36 +1,32 @@ 'use strict'; -const { Router } = require('express'); const AdminApi = require('./admin-api'); const ClientApi = require('./client-api'); const FeatureController = require('./client-api/feature.js'); +const Controller = require('./controller'); const HealthCheckController = require('./health-check'); const BackstageCTR = require('./backstage.js'); const api = require('./api-def'); -class IndexRouter { +class IndexRouter extends Controller { constructor(config) { - const router = Router(); - this._router = router; - - router.use('/health', new HealthCheckController(config).router()); - router.use('/internal-backstage', new BackstageCTR(config).router()); - router.get(api.uri, (req, res) => res.json(api)); - router.use(api.links.admin.uri, new AdminApi(config).router()); - router.use(api.links.client.uri, new ClientApi(config).router()); + super(); + this.use('/health', new HealthCheckController(config).router); + this.use('/internal-backstage', new BackstageCTR(config).router); + this.get(api.uri, this.index); + this.use(api.links.admin.uri, new AdminApi(config).router); + this.use(api.links.client.uri, new ClientApi(config).router); // legacy support (remove in 4.x) if (config.enableLegacyRoutes) { - router.use( - '/api/features', - new FeatureController(config.stores).router() - ); + const featureController = new FeatureController(config.stores); + this.use('/api/features', featureController.router); } } - router() { - return this._router; + index(req, res) { + res.json(api); } }