Here are few lines of code.I did not understand their function.I have commented in the code the lines that I have not understood.
var express = require('express');
var app = express();
var router = require('./app/router'); //not understood
router(app); //not understood
It will be helpful I anyone can explain their function.
var router = require('./api/router'); //not understood
There is plenty of resources out there explaining this. See e.g. What is this Javascript "require"?
router(app); //not understood
router is a function returned by require('./api/router'). The function takes one parameter app.
What the router function does ? We can't know that as it is a proprietary code located in you filesystem in a ./api/router file.
require function is the easiest way to include modules that exist in separate files.
usage file:
var router = require('./app/router');
router(app);
router function take app as a parameter for their use.
support (/app/router.js) file:
export default function(app) {
// code stuff
}
Related
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
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
Let's say I want a cloud function to have a path such as:
https://[MY_DOMAIN]/login/change_password
How do I achieve the "login/" part in Node?
Or even something more complicated such as
login/admin/get_data
?
I tried using
module.exports = {
"login/change_password" = [function]
}
But I got an error when deploying and "change_password" was omitted, so it only tried to deploy a "login" function.
Another thing I tried was using express routers but that resulted in only deploying a single function, which routed to the right path (e.g. myfunction/login/change_password) which is problematic as I have to deploy in bulk every time and can't deploy a function individually.
If you want the flexibility to define routes (paths) that are more complex than just the name of the function, you should provide an Express app to Cloud Functions. The express app can define routes that add path components to the base name of the function you export from index.js. This is discussed in the documentation for HTTP functions. For example:
const functions = require('firebase-functions');
const express = require('express');
const app = express();
app.get('/some/other/path', (req, res) => { ... });
exports.foo = functions.https.onRequest(app);
In that case, all your paths will hang off of the path prefix "foo".
There is also an official samples illustrating use of Express apps: https://github.com/firebase/functions-samples/tree/master/authorized-https-endpoint
Thanks to the discussion with Doug Stevenson I was able to better phrase my question and find that it was already answered in this question.
So this would be an example of my implementation:
const functions = require('firebase-functions');
const express = require('express');
const login = require('./login.js');
const edit_data = require('./edit-data.js');
const login_app = express();
login_app.use('/get_uuid', login.getUUID);
login_app.use('/get_credentials', login.getCredentials);
login_app.use('/authorize', login.authorize);
const edit_data_app = express();
edit_data_app.use('/set_data', edit_data.setData);
edit_data_app.use('/get_data', edit_data.getData);
edit_data_app.use('/update_data', edit_data.updateData);
edit_data_app.use('/remove_data', edit_data.removeData);
exports.login = functions.https.onRequest(login_app);
exports.edit_data = functions.https.onRequest(edit_data_app);
My takeaway from this is that there is a one-to-one Express app to HTTP function correspondence, so if I wanted to have 3 different functions I would need 3 Express apps.
A good balance is to have one app and one function per module (as shown above), which also means you can separate out your functions across several modules/javascript files for ease of maintenance.
In the above example, we can then trigger those HTTP functions using
https://[DOMAIN]/login/get_uuid/
or, from the firebase functions shell
login.get("/get_uuid")
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);
I’m implementing a RESTful API using Node and Express. When it comes to routing, currently it looks like this:
var cat = new CatModel();
var dog = new DogModel();
app.route('/cats').get(cat.index);
app.route('/cats/:id').get(cat.show).post(cat.new).put(cat.update);
app.route('/dogs').get(dog.index);
app.route('/dogs/:id').get(dog.show).post(dog.new).put(dog.update);
I don’t like this for two reasons:
Both cat and dog models are instantiated whether I need them or not.
I have to repeat /cats and /dogs for every path schema
I’d love to have something like this (not working, of course):
app.route('/cats', function(req, res)
{
var cat = new CatModel();
this.route('/').get(cat.index);
this.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.route('/dogs', function(req, res)
{
var dog = new DogModel();
this.route('/').get(dog.index);
this.route('/:id').get(dog.show).post(dog.new).put(dog.update);
});
Is there a clean way in modern Express without any further modules (like express-namespace)? I could go for separate routers for each model and assigning them with app.use('/cats', catRouter). However, what if I have more than one hierarchy level like '/tools/hammers/:id'? I would then have routers within routers within routers, which seems like overkill to me.
I would then have routers within routers within routers, which seems like overkill to me.
Perhaps, but that is the built-in method of prefixing -- to app.use() a Router().
var cats = express.Router();
app.use('/cats', cats);
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
// ...
And, to have one Router .use() another to define multiple depths:
var tools = express.Router();
app.use('/tools', tools);
var hammers = express.Router();
tools.use('/hammers', hammers);
// effectively: '/tools/hammers/:id'
hammers.route('/:id').get(...);
Though, to be closer to your 2nd snippet, you can define a custom method:
var express = require('express');
express.application.prefix = express.Router.prefix = function (path, configure) {
var router = express.Router();
this.use(path, router);
configure(router);
return router;
};
var app = express();
app.prefix('/cats', function (cats) {
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.prefix('/dogs', ...);
app.prefix('/tools', function (tools) {
tools.prefix('/hammers', function (hammers) {
hammers.route('/:id').get(...);
});
});
Check out the new Router in Express 4. It sounds exactly what you're looking for.