[MediaWiki-commits] [Gerrit] mediawiki...cxserver[master]: Refactor the API router to ES6 class
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/377739 ) Change subject: Refactor the API router to ES6 class .. Refactor the API router to ES6 class In follow ups, we are trying to make the router a simple path to handler mapper and handlers in seperate files. This refactoring will help us to provide v2 of apis in future without much code duplication. Change-Id: I10009261b311c80fdea4c300199b73a44880cbe4 --- M lib/routes/v1.js 1 file changed, 288 insertions(+), 216 deletions(-) Approvals: jenkins-bot: Verified Nikerabbit: Looks good to me, approved diff --git a/lib/routes/v1.js b/lib/routes/v1.js index c4b2986..8ba2cf7 100644 --- a/lib/routes/v1.js +++ b/lib/routes/v1.js @@ -1,267 +1,339 @@ 'use strict'; -var app, router, registry; const sUtil = require( '../util' ), jwt = require( 'jsonwebtoken' ), CXConfig = require( '../Config.js' ); -/** - * The main router object - */ -router = sUtil.router(); +class Routes { + constructor( app, registry ) { + this.app = app; + this.registry = registry; + this.router = sUtil.router(); + if ( !this.app ) { + throw new Error( 'Missing app property' ); + } + if ( !this.registry ) { + throw new Error( 'Missing registry property' ); + } + this.registerRoutes(); + } -router.get( '/page/:language/:title/:revision?', function ( req, res ) { - var sourceLanguage = req.params.language, - title = req.params.title, - revision = req.params.revision, - CXSegmenter = require( __dirname + '/../segmentation/CXSegmenter.js' ), - PageLoader = require( __dirname + '/../pageloader/PageLoader.js' ), - pageloader = new PageLoader( app ); + /** +* route definitions +*/ + get routes() { + return { + '/page/:language/:title/:revision?': this.fetchPage, + 'POST /mt/:from/:to/:provider?': this.machineTranslate, + '/dictionary/:word/:from/:to/:provider?': this.dictionary, + '/list/tool/:tool': this.listTool, + '/list/pair/:from/:to': this.listToolForLanguagePair, + '/languagepairs': this.listLanguagePairs, + '/list/languagepairs': this.listLanguagePairs, + '/list/:tool/:from?/:to?': this.listToolForLanguagePairsAndTool, + 'POST /translate/:from/:to/:provider?': this.translate + }; + } - return pageloader.load( title, sourceLanguage, revision ).then( - function ( response ) { - var segmenter, segmentedContent; + /** +* It goes through each route defition, figures out the verb/action to use +* (default: get), the function to call to handle the request and registers +* the whole for the given path. +*/ + registerRoutes() { + const routes = this.routes; + + Object.keys( routes ).forEach( ( path ) => { + let parts = path.split( ' ' ); + let verb = parts[ 1 ] ? parts[ 0 ] : 'get'; + verb = verb.toLowerCase(); + if ( !routes[ path ] ) { + throw new Error( `Could not find handler for path ${path}` ); + } + this.router[ verb ]( parts[ 1 ] || parts[ 0 ], routes[ path ].bind( this ) ); + } ); + } + + fetchPage( req, res ) { + var sourceLanguage = req.params.language, + title = req.params.title, + revision = req.params.revision, + CXSegmenter = require( __dirname + '/../segmentation/CXSegmenter.js' ), + PageLoader = require( __dirname + '/../pageloader/PageLoader.js' ), + pageloader = new PageLoader( this.app ); + + return pageloader.load( title, sourceLanguage, revision ).then( + ( response ) => { + var segmenter, segmentedContent; + + try { + this.app.logger.log( 'debug', 'Fetch page', { + title: title, + sourceLanguage: sourceLanguage + } ); + segmenter = new CXSegmenter( response.body, sourceLanguage ); + segmenter.segment(); + segmentedContent =
[MediaWiki-commits] [Gerrit] mediawiki...cxserver[master]: Refactor the API router to ES6 class
Santhosh has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/377739 ) Change subject: Refactor the API router to ES6 class .. Refactor the API router to ES6 class In follow ups, we are trying to make the router a simple path to handler mapper and handlers in seperate files. This refactoring will help us to provide v2 of apis in future without much code duplication. Change-Id: I10009261b311c80fdea4c300199b73a44880cbe4 --- M lib/routes/v1.js 1 file changed, 281 insertions(+), 223 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/cxserver refs/changes/39/377739/1 diff --git a/lib/routes/v1.js b/lib/routes/v1.js index 77fb8d1..3f29352 100644 --- a/lib/routes/v1.js +++ b/lib/routes/v1.js @@ -1,274 +1,332 @@ 'use strict'; -var app, router, registry; +let registry; const sUtil = require( '../util' ), jwt = require( 'jsonwebtoken' ), CXConfig = require( '../Config.js' ); -/** - * The main router object - */ -router = sUtil.router(); +class Routes { + constructor( app, registry ) { + this.app = app; + this.registry = registry; + this.router = sUtil.router(); + if ( !this.app ) { throw new Error( 'Missing app property' ); } + this.registerRoutes(); + } -router.get( '/page/:language/:title/:revision?', function ( req, res ) { - var sourceLanguage = req.params.language, - title = req.params.title, - revision = req.params.revision, - CXSegmenter = require( __dirname + '/../segmentation/CXSegmenter.js' ), - PageLoader = require( __dirname + '/../pageloader/PageLoader.js' ), - pageloader = new PageLoader( app ); + /** +* routes definitions +*/ + get routes() { + return { + '/page/:language/:title/:revision?': this.fetchPage.bind( this ), + 'POST /mt/:from/:to/:provider?': this.machineTranslate.bind( this ), + '/dictionary/:word/:from/:to/:provider?': this.dictionary.bind( this ), + '/list/tool/:tool': this.listTool.bind( this ), + '/list/pair/:from/:to': this.listToolForLanguagePair.bind( this ), + '/list/languagepairs': this.listLanguagePairs.bind( this ), + '/list/:tool/:from?/:to?': this.listToolForLanguagePairsAndTool.bind( this ), + 'POST /translate/:from/:to/:provider?': this.translate.bind( this ) + }; + } - return pageloader.load( title, sourceLanguage, revision ).then( - function ( response ) { - var segmenter, segmentedContent; + /** +* It goes through each route defition, figures out the verb/action to use +* (default: get), the function to call to handle the request and registers +* the whole for the given path. +*/ + registerRoutes() { + var routes = this.routes; + + Object.keys( routes ).forEach( ( path ) => { + let parts = path.split( ' ' ); + let verb = parts[ 1 ] ? parts[ 0 ] : 'get'; + path = parts[ 1 ] || parts[ 0 ]; + verb = verb.toLowerCase(); + this.router[ verb ]( path, routes[ path ] ); + } ); + } + + fetchPage( req, res ) { + var sourceLanguage = req.params.language, + title = req.params.title, + revision = req.params.revision, + CXSegmenter = require( __dirname + '/../segmentation/CXSegmenter.js' ), + PageLoader = require( __dirname + '/../pageloader/PageLoader.js' ), + pageloader = new PageLoader( this.app ); + + return pageloader.load( title, sourceLanguage, revision ).then( + function ( response ) { + var segmenter, segmentedContent; + + try { + this.app.logger.log( 'debug', 'Fetch page', { + title: title, + sourceLanguage: sourceLanguage + } ); + segmenter = new CXSegmenter( response.body, sourceLanguage ); + segmenter.segment(); + segmentedContent = segmenter.getSegmentedContent(); + this.app.logger.log( 'debug', 'Segment page', { + title: title, + sourceLanguage: