Node Express: does order of calls matter? - node.js

Node Express documentation gives a hello-world example:
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
Does the order of listen() and get() matter? (could they be swapped?) And what would happen if get() and listen() were called a second time after the first calls as above?

Let's deconstruct the example :
app.listen(3000)
this line attaches your app to a port, in this case 3000. It enables you to access it by typing http://localhost:3000, you typically would not want to change the port you app runs on durig execution.
app.get('/', function (req, res) {
res.send('Hello World!')
})
this is basically a listener, which will be called when you make a GET request to the / route. It tells your app what to answer when you type the url on your browser.
It is attached to the app object, whether the app is running or not, so it can be written before listen, after, or in another file altogether.
In the strange case where you'd have a second listener on the same route, one of them would not be executed. I suggest you test it yourself if you really want to know which takes precedence, here's a sample code :
app.get('/', function (req, res) {
res.send('Will I be executed?')
});
app.get('/', function (req, res) {
res.send('or maybe I will?')
});
app.listen(3000)

Related

Can I shutdown specific route in runtime in the express server?

I have an example
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('hello world');
});
In the runtime (for example in 10 sec), I want to stop handling my / endpoint, so when I will make a request, the response would be like Cannot GET /
How can I achieve this behaviour?
You need to create a flag that can be set based on when you want to keep preventing the route from providing the data. Instead of showing Cannot GET /, you should send the status code 503 status code i.e service unavailable.
var express = require('express');
var app = express();
app.get('/', function (req, res) {
if (flag) {
res.status(503).send('Service Unavailable');
} else {
res.send('hello world');
}
});
This could be great if you want to make it for a single route. When you want to control many routes, you can create middleware and use flag similar to the above one.

The server stops working if I wrap express.static in a function

the code below works:
var express = require('express');
var path = require('path');
var app = express();
app.use('/public', express.static("./public"));
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
But if I change the app.use like this:
var express = require('express');
var path = require('path');
var app = express();
app.use('/public', function(){express.static("./public")});
// browser error "cannot GET /
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Why? The server doesn't seem to catch any errors
express.static() returns a middleware function when you call it. You have to pass that specific returned function to app.use(). You don't just call express.static() on every request. You call it once, get the returned function and register that as middleware and app.use() will then call that middleware function on every request.
When you do it the correct way like this:
app.use('/public', express.static("./public"));
It's like doing this:
const fn = express.static("./public");
app.use('/public', fn);
or even like this:
const fn = express.static("./public");
app.use('/public', function(req, res, next) {
fn(req, res, next);
});
Hopefully you can see that this code:
app.use('/public', function(){express.static("./public")});
does not do the same thing as any of the correct solutions. This calls express.static() in every request and never calls the returned function that does the actual work for a given request.
Think of express.static("./public") like a factory function. It creates a middleware function that you then pass to app.use() or call yourself with req, res and next as the arguments.
Why? The server doesn't seem to catch any errors
Executing app.use('/public', function(){express.static("./public")}); is not what you want, but it also doesn't create an error. All it does is create a new middleware function (which you ignore) on every single request. It also never calls next to let any other request handlers handle the request so your server would get stuck on every request, but it never actually causes a visible error.
It essentially becomes functionally equivalent to this:
app.use('/public', function(req, res, next) {
// do nothing, just causes the request to get stuck since
// the request is not handled (no response is sent)
// and next is never called
});
The request is never handled and never calls next to advance to other route handlers so the request just gets stuck and will eventually time out.
You can try with:
app.use(express.static(path.resolve(__dirname, './public'), { maxAge: '1d' }));

Can I pass multiple functions to an http.createServer in NodeJS?

I'm completely new to server development and NodeJS, so my apologies if this question sounds stupid or if such a question already exists.
I was following a simple NodeJS tutorial and building a simple "Hello World" server. I noticed that http.createServer took only one function as its argument.
http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end("Hello World");
}.listen(8080);
I tried passing another function to it like the following:
var http = require('http');
http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type':'text/html'});
res.end("Hello World");
},
function (req, res) {
res.write("Blahblah");
res.end();
}
).listen(8080);
But hitting localhost:8080 returned only Hello World.
So I was wondering if I could pass multiple functions to it and if not, then why.
Thank you for your time
You cannot pass multiple functions. If you want multiple listeners for incoming requests, you can just register another listener for incoming requests:
const server = http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end("Hello World");
}.listen(8080);
// add additional listener
server.on('request', function(req, res) {
if (req.url === "/goodbye") {
res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end("goodbye");
}
});
Note: right from the doc for http.createServer(), it says this about the function parameter passed to http.createServer():
http.createServer([options][, requestListener])
The requestListener is a function which is automatically added to the 'request' event.
Doc for the request event is here.
As others have said, it is pretty rare to use a plain http server like this because some simple routing is nearly always helpful and a lightweight framework like Express offers very useful features without really getting in the way of anything you might want to do. In the case of Express, you'd use code like this:
const express = require('express');
const app = express();
// define handler for /goodbye URL
app.get('/goodbye', function(req, res) {
res.send("goodbye");
});
// define handler for /hello URL
app.get("/hello", function(req, res) {
res.send("hello");
});
const server = app.listen(8080);
Here express, keeps a list of the URLs that you wish to handle and then listens for each incoming request, compares it against the URLs you wanted to handle and calls the appropriate route handler. It has lots of other features for routing too such as middleware, wildcards, parameterized URLs, etc...
I'd recommend you use something like express if you want multiple routes:
const express = require('express');
const app = express();
app.get('/hello', (req, res) => res.send('Hello World!'));
app.get('/world', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Example app listening on port 3000!'));
Node.js provides you with the features to create your own webserver from scratch, unless you want to create a whole new framework i would recommend using something like expressjs.
Have a look at this following tutorial if you're a newbie and want to create restful services.
Build a RESTful API Using Node and Express 4 | Scotch.io
Its a fairly simple and straightforward tutorial

.on('connection') for an express server

I am trying to create a basic web server with express for node.js. I know that the http module has a .on('connection',function(client){}) method that is called whenever a client connects. Is there a similar method for express?
I know this question is quite old, but I had the same one and was able to figure out the answer, so I thought I would post it here for anyone else who may be looking.
According to the Express docs with Express 4.x, the listen method returns an http.Server object, so all methods that can be used on http.Server.listen are also available on the Express listen method.
With this in mind, the answer to your question is yes, and below is an example of how you can achieve it in Express 4.x.
const app = express();
app.use('/', function (req, res, next) {
// Add your code for this route here
});
const server = app.listen(3000, function () {
console.log('Server listening on port 3000');
});
server.on('connection', function (client) {
// Do your thang here
});
You can easily add a route that will be matched against "everything", that is:
app.use('/', function (req, res, next) {
console.log("received request: " + req.originalUrl);
next();
});
This is simply a middleware that, once a client executes any rest api to your server, will log the url and call next() to continue to the next matching route

What all can app.get in express be used for?

It can be used for
app.get('/', function(req, res){
res.send('hello world');
});
which is to display in browser upon receiving request on Port defined.
What other uses are there of the command app.get?
app.get has two uses.
the first is using it as a route just like you showed,
or even using multiple middlewares additionally to the route like in the following example:
var middleware = function(req, res, next) {
//do something, then call the next() middleware.
next();
}
app.get('/', middleware, function (req, res) {
res.render('template');
});
but app.get can also be used together with app.set:
var appEnv = app.get('env'); //tells you the environment, development or production
var appPort = app.get('port'); //tells you the port the app runs on
console.log('app is running in ' + appEnv + ' environment and on port: ' + appPort);
app.set('any-string', 'any value'); //set custom app level value
var any_string = app.get('any-string'); //retrieve custom app level value
console.log('any_string = ' + any_string);
thats the uses for app.get i found so far,
have fun
jascha
In express app.get or app.post is used to define a route. Both of them work the same way. They accept two parameters
1) A string that defines the path of the route
2) A single or multiple callbacks.
app.get('/', function(req, res){
res.send('hello world');
});
What the above code does is it tells express that when a request is made on / endpoint it executes the code in the callback function. The function that you have defined just sends an html message
However there are lot's of different responses that you can send to the browser. They are enumerated in the guide

Resources