Node Express

From Logic Wiki
Jump to: navigation, search

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