I just started learning express and I read that an express middleware is a Javascript function to handle HTTP requests. It accepts 3 parameters:- req, res and next.
When I tried the following code block:-
const express = require('express');
const app = express();
var x = app.get('/', function(req, res){
res.send('Hello World!');
} );
console.log(x.toString());
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
} );
I see the following output:-
function(req, res, next){
app.handle(req, res, next);
}
So is the express app object also an express middleware?
I'm sorry if this is a silly question, but wanted to have an insight nevertheless.
The .get() function is yes. the majority of the express functions .use() etc are really just middlewares for specific tasks. .get checks the req object against the url provided, if it's a match then it runs it's code. If it isn't then it continues to next() through all the other .get() middlewares.
The entire ecosystem of express is middlewares going to more middlewares
Related
I have a few api calls set up via express and router. I am trying to debug and understand the working of the router. I have a logger set up, and trying to log all the api calls. However, the calls are never logged. All the api endpoints get called and the application works as expected though. Below is an example of what I am trying to do. Can someone please let me know what could be missing here?
const logger = require('./config');
const app = express();
// routes needed for the app
app.use(require('./routes/apis'));
app.use('/api', (req, res, next) => {
logger.info('in /api call');
});
you need to change the order of the middleware:
const logger = require('./config');
const app = express();
app.use('/api', (req, res, next) => {
logger.info('in /api call');
});
// routes needed for the app
app.use(require('./routes/apis'));
When I put app.use(bodyParser.json()); below app.use('/api', require('./routes/api'))
req.body returns undefined. But if I put app.use(bodyParser.json()); above app.use('/api', require('./routes/api')); it returns correctly. So the question is why?
Here is my code:
index.js file
const express = require('express');
const app = express();
const bodyParser= require('body-parser');
app.use(bodyParser.json());
app.use('/api', require('./routes/api'));
app.listen(process.env.port || 3000, function(){
console.log('You are listening to port 3000');
});
api.js file
const express= require('express');
const router= express.Router();
router.get('/ninjas', function(req, res){
res.send({type: 'GET'});
});
router.post('/ninjas', function(req, res){
console.log(req.body);
res.send({type: 'POST'});
});
router.put('/ninjas/:id', function(req, res){
res.send({type: 'PUT'});
});
router.delete('/ninjas/:id', function(req, res){
res.send({type: 'DELETE'});
});
module.exports =router;
Thanks in advance!
We need body-parser middleware to read from req.body,
In Javascript code executes line by line (for non IO operations).
So when you place app.use(bodyParser.json()) after requiring your router file logic, body-parser is not invoked and plugged, so you need to invoke it before any other logic, so that you can read from the request.
Bodyparser is a middleware which should run everytime when a route is accessed.
A middleware (like bodyparser) is written like this
const middleware = (req, res, next) => {
//some code here
next();
}
The next function starts the execution of another middleware function
So when you use the bodyparser middleware after the routes req.body will not be initialized because the bodyparser middleware never ran for the route and the response ends with the res.send().
But if you use the bodyparser middleware before initializing the routes the bodyparser middleware will always run.
You can see more examples on middleware in the expressjs docs
https://expressjs.com/en/guide/using-middleware.html
I am trying to learn middleware in express js. Could anyone help where I am missing? Here is my code
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var app = express();
app.use("/", function(req, res, next){
console.log("this is my second output");
next();
});
app.get('/', function(req,res){
console.log("this is my first output");
//res.send('Hello World');
});
app.listen(3000, function(){
console.log('Server started on port 3000...');
})
I am getting Server started on port 3000.. when I run on cmd and getting "page is not working" on localhost:3000
Edited
I got
Server started on port 3000...
this is my second output
this is my first output
this is my second output
this is my first output
this is my second output
this is my first output
this is my second output
this is my first output
this is my second output
this is my first output
this is my second output
this is my first output
this is my second output
this is my first output
after some time. But localhost:3000 is still not working
The reason you get the "page is not working" message is because your application does not respond to any request it receives.
You'll need to uncomment that res.send('Hello World'); in app.get('/', ...). After that your code works perfectly fine.
Note, however, that in the structure of your code, your middleware app.use(...) is called before you get to the main logic for the route (app.get(...)), contrary to what's indicated by your console.log calls.
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var app = express();
// use this middleware to pass all the requests
app.use("/", function(req, res, next){
console.log("this is my second output");
// move to next middleware
next();
});
//handle all the get requests to localhost:3000 url
app.get('/', function(req,res){
console.log("this is my first output");
// send the response
res.send('Hello World');
// or you can send the response like this
// res.json(JSON.stringify({"success":"true"}));
});
app.listen(3000, function(){
console.log('Server started on port 3000...');
})
send a get request to http://localhost:3000
Mainly, Middlewares execution consists of two things: ->
next()
app.use()
const express = require('express');
const app = express();
const hola = function(req, res, next) {
console.log("are you okay?");
next();
console.log("Yes I'm okay....");
}
app.use(hola)
app.get('/',(req, res) => {
res.send('HEY SUDEEPA WELCOME TO OUR SERVER !!!
})
app.listen(3000,() => {
console.log('Server started at port 3000!!!! ');
})
In the above code if we do not mention the next() method in hola function then after clicking localhost:3000 our will got crashed because it is not getting it's next middleware which is our app.get. So, if we are not mentioning next() then it could be our one of reason for not getting executed Middlewares.
Based on Express docs, a middleware must run each time app is launched following this code:
var app = express();
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
Well, trying to execute with the most simple possilbe example middleware never is excuted:
var express = require('express');
var middleware = require('./middleware');
var app = express();
app.use(function (req, res, next){
console.log('MIDDLEWARE');
next();
});
module.exports = app;
Middleware never runs.
Also tryed to make it working from a separated file, but never runs.
Thanks
Middleware are lunch when there are any request to the server.
Create a route and send a request to that, the middleware would be lunched.
Ups, seems to be they're launched when recieves a request. So using Postman it worked.
I have trouble implementing route mounting in express.js 4.13.3.
When I first install it, by default created in the app.js
var users = require('./routes/users');//get the "users" route
app.use('/users', users);//mount to "/users"
and the users.js route is like
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('respond with a resource');
});
module.exports = router;
Does not need to define router.get('/users'... because mounting took care of that in the app.js file.
But
When I try to do the same thing
in app.js I set
var upload = require('./routes/upload');
app.get('/upload', upload);//mounting (?)
the upload.js route is
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('upload', {title: 'Photo upload'});
});
module.exports = router;
When I access localhost/users I get 404 error. The only way to fix this , is to define in the upload.js router, this router.get('/upload' instead of this router.get('/'. But that would not be mounting.
The difference I see is that the default code uses app.use('/users', users); and my code uses app.get('/upload', upload);. Is the verb (use/get) the only difference that causes the 404? And if so, why? Or is it something else?
Thanks
You are totally correct that the problem is caused because these to functions work differently. Below are the official API specifications for the functions.
app.use is for mounting a middleware
app.get is for defining (only) one route for a HTTP GET request
This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
This example shows a route and its handler function (middleware system). The function handles GET requests to the /user/:id path.
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});