Node Express
What is Express?
Express is web framework for Node that makes it easy to build web applications. While it is very much possible to build any web application just using Node, Express provides higher-level building blocks and the patterns to stack parts together which makes web development easier.
npm install --save express ejs
Key Pieces of Express
Foundation Layer: HTTP API
In order to build a web application, we need to handle web requests from web browsers. These web requests are made using the HTTP protocol. Node provides a HTTP API (through the http module) to receive and respond to web requests. However, Node's HTTP API is a low-level API.
The reasoning to have a low-level API is best explained in the Node HTTP API docs:
In order to support the full spectrum of possible HTTP applications, Node's HTTP API is very low-level. It deals with stream handling and message parsing only. It parses a message into headers and body but it does not parse the actual headers or the body.
You can read more about Node HTTP API here.
Express provides a higher-level API that is built on top of Node's HTTP API. This API makes it easier to write request handlers for web application requests.
To give a simple example, say we are building a web application where we want to perform some logic based on the request url (a common use case).
If we use just Node's HTTP module, we can get the request's url by using request.url in our code. However, if we need to extract the different pieces of this request url, we will need manually parse it through code or use another module like 'url' (this is not hard, but more code for us to write). On the other hand, if we were using Express, then it already splits this request.url to provide us with the different pieces like request.path, request.params, request.query.
You can read more about the Express HTTP API here
Glue Layer: Middleware
For an incoming web request, Express enables it to be passed though a series of request handler functions called Middleware. This approach enables Express to provide a minimalistic set of core functionality within the framework and let the user customize the application by picking and installing middleware.
Middleware is available for everything from request parsing, cookie handling, form validation, user authentication and more.
For this reason, the official Express documentation says that:
An Express application is essentially a series of middleware calls. You can read more about Express Middleware here
Switchboard Layer: Routes
Express enables the handling of an incoming web request by a specific request handler by defining routes. An incoming request is mapped to a request handler using a combination of the method and uri.
Here is an example to map a simple GET request to a /hello route
app.get('/hello', function(req, res) {
res.send('Hello World!');
}
A Router is a series of routes that are bundled together to act as a unit. Here is how the Express documentation describes it:
A Router instance is a complete middleware and routing system; for this reason it is often referred to as a “mini-app” Here are the Express docs on Routing
Display Layer: Views
Express enables responding to web requests though HTML using template engines that make it easy to generate HTML markup. Template engines allow you to loop through collections, embed one view inside another and many other niceties that make view generation easier and more organized.
Here are the Express docs on Views
Summary
In essence, Express is an simple routing and middleware web framework with minimal functionality of its own but instead added to it via third-party middleware.
Sample app.js
var express = require('express');
var path = require('path');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.send('working');
});
var port = 3000;
app.listen(port, function(){
console.log('Server started on port ' + port);
});
Sample app.js
Mosh's sample
var express = require('express');
var app = express();
app.get('/', (req, res)=> {
res.send('working');
});
app.get('/api/courses', (req, res)=> {
res.send(1,2,3);
});
app.listen(3000,()=>{
console.log('Server started on port ' + port);
});
Environment Variables
using process.env.PORT
const port = process.env.PORT || 3000
app.listen(port,()=>{
console.log('Server started on port ' + port);
});
setting env var in Mac
export PORT=5000
in win
set PORT =5000
Parameters
app.get('/api/courses/:id', (req, res) => {
res.send(req.params.id);
});
req.params -> returns a json object with all parameters in it.
Parameter Sample
app.get('/api/courses/:id', (req, res) => {
const course = sourses.find(c=> c.id === parseInt(req.params.id));
if (!course) res.status(404).send('This course with the given ID was not found');
res.send(course);
});
Parameters
app.get('/api/courses/:id', (req, res) => {
res.send(req.params);
});
it returns a json object with all parameters in it.
Multiple Parameters
app.get('/api/courses/:id/:other', (req, res) => {
res.send(req.params.id);
// res.send(req.params); // to display all params in json format
});
Querystring Parameters
for optional parameters
localhost:3000/api/posts/2018/1?sortBy=name
res.send(req.query);
Handling POST requests
app.use(express.json()); // to parse body object
....
app.post('/api/courses', (req, res) ={
const course = {
id : courses.length + 1,
name : req.body.name
}
courses.push(course);
res.send(course);
});
Input validation
npm i joi
const Joi = require('joi'); //-> it's pascal case because it returns a function
...
app.post('/api/courses', (req, res) ={
const schema = {
name:Joi.string().min(3).required()
};
const result = Joi.validate(req.body, schema); / in resut either error or value property becomes null.
if(result.error) {
res.status(400).send(result.error);
// Or with shorter message like
//res.status(400).send(result.error.details[0].message);
return;
}
const course = {
id : courses.length + 1,
name : req.body.name
}
courses.push(course);
res.send(course);
});
Express Middlewares
urlencoded middleware
app.use(express.urlencoded({ extended:true }));
static middleware
app.use(express.static('public'));
public is the folder name where we keep static files
when it's used it's like the root folder. ie : localhost:3000/readme.txt -> even readme.txt is in public folder we don't write it in url
Some Third Party Middlewares
Check http://expressjs.com/en/resources/middleware.html helmet to secure http calls morgan Http request logger
- install them first with npm i morgan
- use require to import
- app.use(... to use