Express js modular REST framework - node.js

I am planning to develop only rest api using express js, I looked into lot of boilerplate projects. None of them provide modularity. Modularity I mean all code related to articles module need to be in article folder then I can drag and drop that.
I saw MEAN somewhat close to that but it has client side (angular related) code in that. I need pure rest api framework.

To me it doesn't sound like you want to use a MEN stack, I do not see a reason to use MongoDB in your question. You can write modular express apps e.g. like this:
Assuming you have three modules in three different folders moduleA, moduleB and moduleC. Each folder contains its respective logic and provides some RESTful routes to the outside world. In express you would create one separate Router for each module like this:
ModuleA:
/* moduleA/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleA
module.exports = router;
ModuleB:
/* moduleB/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleB
module.exports = router;
ModuleC:
/* moduleC/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleC
module.exports = router;
And then you would have one main app.js file in your root folder where you enable and disble the single modules by mounting them into the main express app:
/* app.js */
var express = require('express');
var moduleA = require('./moduleA/routes');
var moduleB = require('./moduleB/routes');
var moduleC = require('./moduleC/routes');
var app = express();
... // add your main app's middlewares
app.use('/moduleA', moduleA);
app.use('/moduleB', moduleB);
// app.use('/moduleC', moduleC);
app.listen(3000);
In this example the modules moduleA and moduleB are enabled and are reached by the routes /moduleA/* and /moduleB/* respectively. The module moduleC is disabled as we commented it out.
If you have questions please leave a comment.

It sounds like you want to use a "MEN" stack, which is MongoDB (for backend), Express, and Node.JS.
Here's a tutorial on how to build a project with a "MEN" stack: https://github.com/maslennikov/node-tutorial-men or this one: https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

Related

What is the difference between the two calls to express()

I have 2 require('express) calls.
First:
const express = require('express');
const app = express();
Second:
const Router = require('express');
const router = new Router();
What is the difference, why in the first we call a function, and in the second we create an object, if the methods are the same in both (use, get, post, etc)?
I think your question missed something. Your second example shows this:
const Router = require('express');
... but I think you meant to do this:
const Router = require('express').Router;
... regardless, the following should help you better understand.
In express, you can think of Routers as little mini applications... lightweight express apps... which have their own routing. In fact, the main "express" object is itself a Router. For example, you might have a bunch of endpoints for managing users:
// ./routes/user-routes.js
const userRoutes = new express.Router();
userRoutes.get('/', getAllUsers);
userRoutes.get('/:userId', getUserById);
userRoutes.post('/', createUser);
userRoutes.put('/:id', updateUser);
userRoutes.delete('/:id', removeUser);
Notice how none of the urls have anything like /users/ inside them. This is important because this little mini app can now be "mounted" (for lack of better terms) in a larger express app like follows:
const express = require('espress');
const userRoutes = require('./routes/user-routes');
const app = express();
app.use('/path/to/users', userRoutes);
Notice how the userRoutes were "mounted" on the /path/to/users such that all user requests will happen to the following URLs:
GET /path/to/users - get all users
GET /path/to/users/1234 - get user with id "1234"
... you get the point
This is mostly a convenient way to think about your app as a bunch of smaller mini apps which are orchestrated together.
Your second call is incorrect, you are just calling (requiring) express which is similar to your first call.
I never did const router = new Router();, so I'm not sure what that accomplish.
I generally do-
const router = require('express').Router();
router.get();
Even though with your first call you can do
app.get() and app.post()
According to express explanation
express.Router class is used to create modular, mountable route handlers. A Router instance is a complete middleware and routing system
Read more about it here
GeekforGeeks explains express.Router() very well

Generic route prefix + specific route in Node Express

I have a system where, before specifying the data you want to access, you need to provide the company you are accessing from, to check for authorization.
For example, to get products, materials and users:
GET company/123123/product
GET company/123123/material
GET company/123123/user
When creating the express routes in node JS, I'm using the prefix "company/:id" in all my routes declarations:
app.get("/company/:id/product", callbackProduct);
app.get("/company/:id/material", callbackMaterial);
app.get("/company/:id/user", callbackUser);
The question is, is there any way to generalize this 'company' part of the route, in a way that I don't need to re-write it in all routes?
For example:
app.something("/company/id:/*", genericCallback);
app.get("/product", callbackProduct);
app.get("/material", callbackMaterial);
app.get("/user", callbackUser);
What you could do is to use express.Router.
In an company.routes.js you would write something like that.
const express = require("express");
const CompanyRouter = express.Router();
CompanyRouter.get("/:id/product", callbackProduct);
CompanyRouter.get("/:id/material", callbackMaterial);
CompanyRouter.get("/:id/user", callbackUser);
module.exports = CompanyRouter;
And in your server.js file you would do the following.
const express = require("express");
const CompanyRouter = require("./path/to/CompanyRouter.js")
const app = express();
app.use("/company", CompanyRouter);
app.listen(3000);

Nodjs swagger auto gen integration

I need to develop an API using NodeJS and also need to develop documentation for API also. I integrated with swagger auto-gen for swagger.json creation. But the swagger.json not generating properly if I used routes.js as below
var express = require('express');
module.exports = function(app) {
var userController = require('../controller/userController');
var apiRouter = express.Router();
var routerV1 = express.Router();
var routerV2 = express.Router();
app.use('/admin', apiRouter);
apiRouter.use("/v1", routerV1);
apiRouter.use("/v2", routerV2);
routerV1.route('/users').get(userController.getUsersV1);
routerV2.route('/users').get(userController.getUsersV2);
}
and also mapped these routes.js in swagger.js
Please suggest the best way to generate swagger.js
Do we need to create routes file for all controller?
Version 2 of swagger-autogen added this feature. Previous versions don't recognize routes. In your case, the best way to generate the file swagger.js is:
file: swagger.js
const swaggerAutogen = require('swagger-autogen')();
const outputFile = './swagger_output.json';
const endpointsFiles = ['./routes.js']; // root file where the route starts.
swaggerAutogen(outputFile, endpointsFiles).then(() => {
require('./index.js'); // Your project's root file
})
Update your module to the latest version.
And run your project with: node swagger.js
And about the routes file for all controller, you don't need to implement it for each one, but it also depends on the structure of your code. If you have a root route file like the example, this is enough for all sub-routes to be scanned. I hope it helps you. Take a look at this example if you need to:
swagger-autogen using router

How to automatically include routes in ExpressJS

Let's say you always wanted to do certain prefixes on routes, such as /before and to pop that off after a certain line in your server.js file.
Here's an example
const express = require('express');
const App = express();
App.get('/before') //so here the route is '/before'
App.push('/after') //This is a made up method, but something like this has to exist...
App.get('/before') //And this route would be '/after/before'
App.pop(); //Another made up method
App.get('/before') //and this would be just "/before"
This isn't exactly the .push() and .pop() design, but it lets you accomplish the same goal of grouping routes under a common parent path without having to specific the common parent path on each route definition.
Express has the concept of a separate router. You define a bunch of routes that want to share a common parent path on a router. You then register each leaf path on the router and then register the whole router on the parent path.
Here's an example:
const express = require('express');
const app = express();
const routerA = express.Router();
// define routes on the router
routerA.get("/somePath1", ...);
routerA.get("/somePath2", ...);
routerA.get("/somePath3", ...);
// hook the router into the server at a particular path
app.use("/parentPath", routerA);
app.listen(80);
This registers three routes:
/parentPath/somePath1
/parentPath/somePath2
/parentPath/somePath3

Can I pass variable to required file?

In express, I'm trying to move my minification to a requierd file:
app.js:
var app = express();
var minify = require("./minify.js");
In that file I try to set my template engine.
minify.js:
var app = express();
app.engine('html', mustacheExpress());
Later when I try to use to use the rendering engine in app.js, I get the error that no template-engine is set. It works if I run it all in the same file. I think the problem is that I declare the app-variable twice. How can I pass the app-variable into minify.js?
The problem is that you define new app variable, and you currently instantiate brand new express instance by calling express().
What you need to do is start using functions so that you can pass params (there are other methods too, but this is one that will work for you):
// app.js
var app = express();
var minify = require('./minify'); // don't include .js!
minify(app); // CALL the function that minify.js exports, passing params
// minify.js
module.exports = function(app) {
// because app comes as a parameter, it's the very same you've created in app.js
app.engine('html', mustacheExpress());
}
Again, there are many different methods and maybe proper approaches, depending on what you want to do, but this will do the job in your case. Read more about NodeJS and it's require system.
You can pass 'app' from app.js to your minify by using function in your module like Andrey said. You can do it like this too for example :
minify.js
module.exports = {
setAppEngine : function(app) {
app.engine( [...] );
}
}
And calling it like this in your app.js:
app.js
var app = express();
var minify = require("./minify.js").setAppEngine(app);
This solution is very useful because you can set and call others methods in minify.js. For example, you can do with the same code in minify.js:
app.js
var app = express();
var minify = require("./minify.js");
minify.setAppEngine(app);

Resources