Skip to content

Commit

Permalink
Improved API logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
kallaspriit committed Apr 7, 2016
1 parent 39b6e0b commit 7807bae
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 36 deletions.
37 changes: 36 additions & 1 deletion controllers/user/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,45 @@ import AbstractController from '../../lib/server/AbstractController';
import joi from 'joi';

export default class UserController extends AbstractController {

constructor() {
super();

this.users = [{
id: 1,
name: 'Jack Daniels'
}, {
id: 2,
name: 'Jill Pipers'
}];
}

get() {
return {
description: 'Fetches requested user info',
description: 'Fetches information about a selected user',
path: '/:id',
parameters: {
id: joi.number().min(1)
},
run(parameters) {
const id = parameters.id;

console.log('find', id, this);

const user = this.users.find((item) => item.id === id);

if (!user) {
throw new Error('User with id "' + id + '" was not found');
}

return user;
}
};
}

getUser() {
return {
description: 'Fetches list of all users',
parameters: {
id: joi.number().min(1)
},
Expand Down
147 changes: 115 additions & 32 deletions lib/server/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import glob from 'glob';
import restify from 'restify';
import bodyParser from 'body-parser';
import cors from 'cors';
import normalizeType from 'normalize-type';
import httpStatus from 'http-status';
import logger from '../logger';

const log = logger.get(__filename);
Expand Down Expand Up @@ -44,20 +46,28 @@ export default class Server {
}

setupCurlSupport() {
this.handler.pre(restify.pre.userAgentConnection());
log('setting up CURL support');

this.handler.pre(
restify.pre.userAgentConnection()
);
}

setupCors() {
log('setting up CORS');

// allow cors from all requests
this.handler.use(cors());
this.handler.use(
cors()
);
}

setupQueryParser() {
log('setting up body parser');
log('setting up query parser');

this.handler.use(restify.queryParser());
this.handler.use(
restify.queryParser()
);
}

setupBodyParser() {
Expand All @@ -72,19 +82,20 @@ export default class Server {
setupGlobalRoute() {
log('setting up global route');

this.handler.use((req, res, next) => {
this.updateStatistics(req, res);

next();
});
this.handler.use(
(...args) => this.handleGlobalRoute(...args)
);
}

setupIndexRoute() {
log('setting up index route');

this.register('index', Method.GET, '/', (req, res) => {
res.send('index route response: ' + this.statistics.requestCount);
});
this.register(
'index',
Method.GET,
'/',
(...args) => this.handleIndexRoute(...args)
);
}

setupAppRoutes() {
Expand All @@ -96,47 +107,119 @@ export default class Server {
}));
}

getControllersInDirectory(directory) {
const controllersPattern = path.join(directory, '**/*.js');
const controllerFilenames = glob.sync(controllersPattern);

return controllerFilenames.map((controllerFilename) => {
const controller = {
name: 'user', // TODO
handler: 'index',
filename: controllerFilename,
include: require(controllerFilename),
instance: null
};

return controller;
});
}

setupControllers() {
this.controllers = this.getControllersInDirectory(this.config.controllersDirectory).map(
(controller) => this.setupController(controller)
);
}

setupController(controller) {
controller.instance = new controller.include.default(); // eslint-disable-line new-cap

for (const methodName in controller.instance) {
if (!controller.instance.hasOwnProperty(methodName)) {
continue;
}

log('controller', controller.name, 'method', methodName);
}

const descriptor = controller.instance.get();
const actionPath = this.resolveControllerActionPath(controller, descriptor);
const routePath = '/' + controller.name + actionPath;

this.register(
controller.name,
Method.GET,
routePath,
(req, res, next) => this.handleControllerRoute(controller, descriptor, req, res, next)
);

this.register(controller.name, Method.GET, '/' + controller.name, (req, res, next) => {
const response = descriptor.run(req.params);
log('setup controller', controller, descriptor);

res.send(response);
return controller;
}

next();
});
resolveControllerActionPath(controller, descriptor) {
if (typeof descriptor.path === 'string') {
return descriptor.path;
} else if (typeof descriptor.path === 'function') {
return descriptor.path();
}

log('setup controller', controller, descriptor);
return '';
}

return controller;
handleIndexRoute(req, res, next) { // eslint-disable-line no-unused-vars
res.send('index route response: ' + this.statistics.requestCount);
}

getControllersInDirectory(directory) {
const controllersPattern = path.join(directory, '**/*.js');
const controllerFilenames = glob.sync(controllersPattern);
handleGlobalRoute(req, res, next) {
this.updateStatistics(req, res);

return controllerFilenames.map((controllerFilename) => {
const controller = {
name: 'user',
handler: 'index',
filename: controllerFilename,
include: require(controllerFilename),
instance: null
};
next();
}

controller.instance = new controller.include.default(); // eslint-disable-line new-cap
handleControllerRoute(controller, descriptor, req, res, next) {
const normalizedParameters = normalizeType(req.params);

return controller;
try {
const response = descriptor.run.call(controller.instance, normalizedParameters);

this.sendSuccessResponse(res, response);
} catch (e) {
log(e, 'Handling controller request failed');

this.sendErrorResponse(res, e);
}

next();
}

sendSuccessResponse(res, data) {
res.send(httpStatus.OK, {
data: data,
error: null
});
}

sendErrorResponse(res, error) {
res.send(httpStatus.INTERNAL_SERVER_ERROR, {
data: null,
error: this.formatError(error)
});
}

formatError(error) {
return {
message: error.toString(),
trace: this.formatErrorTrace(error.stack)
};
}

formatErrorTrace(trace) {
return trace
.split('\n')
.map((line) => line.trim());
}

updateStatistics(/* req, res */) {
this.statistics.requestCount++;
}
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@
"cors": "^2.7.1",
"express": "^4.13.4",
"glob": "^7.0.3",
"http-status": "^0.2.1",
"inquirer": "^0.12.0",
"joi": "^8.0.5",
"moment": "^2.12.0",
"request": "^2.69.0",
"normalize-type": "^1.2.0",
"request": "^2.70.0",
"restify": "^4.0.4",
"serve-static": "^1.10.2"
},
"devDependencies": {
"babel-cli": "^6.6.5",
"babel-eslint": "^5.0.0",
"babel-eslint": "^6.0.2",
"babel-preset-es2015": "^6.6.0",
"babel-preset-stage-0": "^6.5.0",
"eslint": "^2.4.0"
"eslint": "^2.7.0"
}
}

0 comments on commit 7807bae

Please sign in to comment.