Express (express)

  • Secondary encapsulation is performed based on HTTP services
  • A lot of middleware is extended in Express
  • Routes are encapsulated
  • Req, RES encapsulates some functions

About the differences between Express and KOA middleware

  • Koa is compact and does only basic packaging
  • Express has a lot of additional middleware, routing

Simple to use

NPM install Express express.js is required

let express = require('.. /node_modules/express');
let app = express();
app.get('/',(req,res)=>{
  res.end('ok'+req.money);
});
app.get('/hello', (req, res) => {
  res.end('hello');
});
app.delete('/hello', (req, res) => {
  res.end('delete hello');
});
app.post('/hello',(req,res)=>{
  res.end('post hello');
});
app.all(The '*',(req,res)=>{
  res.end('end'); });// Send static files
app.get('/ 404'.function (req,res) {
  res.sendFile('404.html', {root:__dirname});// Absolute paths must be guaranteed
  //res.sendFile(require('path').join(__dirname,'404.html'));
})
app.listen(3000);
Copy the code

We can see from the above:

  • Express is a function
  • Functions such as DELETE, POST, all, etc., deal with routing
  • Express returns a listener function
  • This function can start a service
  • There are many things you can do before accessing the route => middleware

Express express/shelf index. Js


let http = require('http');
let url = require('url');
function createApplication(){
    // If the method is requested and the path is consistent, the callback is executed
    let app = (req,res) = > {
        let reqMethod = req.method.toLowerCase();
        let {pathname} = url.parse(req.url,true);
        for(let i=0; i<app.routes.length; i++){let {method,path,handler} = app.routes[i];
            if(method === reqMethod && pathname == path){
                handler(req,res)
            }
        }
        res.statusCode = 404;
        res.end(`Cannot ${reqMethod} ${pathname}`);
    }
    app.routes = [];
    // Store method path callback
    app.get = (path,handler) = > {
        app.routes.push({
            method:'get',
            path,
            handler
        })
    }
    app.listen = (. args) = > {
        letserver = http.createServer(app); server.listen(... args); }return  app;
}
module.exports = createApplication
Copy the code

Post test: you can download the Postman plug-in to download and install it

all

function createApplication(){... let app =(req,res) = >{... for(let i=0; i<app.routes.length; i++){let {method,path,handler} = app.routes[i];
            if((method === reqMethod || method === all)&& (pathname == path|| pathname === The '*')){
                handler(req,res)
            }
        }
        res.statusCode = 404;
        res.end(`Cannot ${reqMethod} ${pathname}`);
    }
    app.all = function (path, handler) {
        app.routes.push({
          method: 'all',
          path,
          handler
        })
    }
    ...
}
Copy the code

The onion model

express/test1.js

function app(){

}
app.routes = [];
app.use = function(cb){
    app.routes.push(cb)
}

app.use((next) = > {
    console.log(1);
    next();
    console.log(2);
})
app.use((next) = > {
    console.log(3);
    next();
    console.log(4);
})    
app.use((next) = > {
    console.log(5);
    console.log(6);
})  

let index = 0;
function next(){
    if(index === app.routes.lenth) return;
    app.routes[index++](next)
}
next();
Copy the code

Output 135642, that’s what we call the Onion model

The middleware

  • Middleware can do a lot of things before we actually access the routing
  • You can decide whether to execute down
  • Can do some permissions, can write multiple middleware, and routing is placed in the same queue
  • Req is the same thing
  • It’s like the onion model

express.js

app.use('/', (req,res,next)=> {
  req.money = 10000;
  next();// If next is not called, it will not continue
});
app.use((req, res, next) = >{
  req.money -= 2000;
  next();
});
app.get('/',(req,res)=>{
  res.end('ok'+req.money);
});
Copy the code

Finally localhost:3000 prints OK 3000

The middleware implements Express /index.js

. function createApplication(){let app = (req,res) = > {
        let reqMethod = req.method.toLowerCase();
        let {pathname} = url.parse(req.url,true);
        let index = 0;
        function next(){// Convert the callback to the next form
            if(index === app.routes.length){
                res.statusCode = 404;
                res.end(`Cannot ${reqMethod} ${pathname}`);
                return;
            } 
            let {method,path,handler} = app.routes[index++];
            if(method === 'middleware') {/ / middleware
                if(pathname == path || path === '/' || pathname.startsWith(path + '/')){
                    handler(req,res,next)
                }else{
                    next();Execute the next middleware without iteration}}else{
                / / routing
                if((method === reqMethod || method === all)&& (pathname == path|| pathname === The '*')){
                    handler(req,res);
                }else{
                    next();
                }
            }
        }
        next();
    }
    app.routes = [];
    // Store method path callback
    let methods = ['get'.'post'.'put'.'delete'.'options'];
    app.use = function(path,handler){
        if(typeofhandler ! ='function'){
            handler = path;
            path = '/'
        }
        app.routes.push({
            method: 'middleware',
            path,
            handler
        })
    }
    ...
    return  app;
}
module.exports = createApplication
Copy the code

In particular, if our path is article/9/ ZDL, we say article/:age/:name => {age:9,name: ZDL}

How do you parse this path? It is available in Express via req.params

express.js

let express = require('.. /express');
let app = express();
app.get('/article/:id/:name', (req,res,next)=> {
    console.log(req.params);
    res.end(JSON.stringify(req.params));
});
app.listen(3000);
Copy the code

test: localhost:3000/:1/zdl1

express/index.js

. function createApplication(){let app = (req,res) = >{... function next(){ ... if(method ==='middleware'){
                ...
            }else{
                / / routing
                if(path.params){
                    // Route to path parameter
                    if(path.test(pathname)){
                        let params = {}
                        let values = pathname.match(path).slice(1);
                        values.forEach((value,index) = >{
                            params[path.params[index]] = value
                        });
                        req.params = params; // Mount the parameters to req
                        handler(req,res);
                    }else{ next(); }}else{... } } } next(); }... methods.forEach(method= > {
        app[method] = (path,handler) = > {
            // Route with path parameters
            let params = [];
            if(path.includes(':')) {// Convert the path to a re if it has:
                path = path.replace(/:([^\/]+)/g.function(){
                    params.push(arguments[1]);
                    return '(/ [^ \] +)';
                })
                path = new RegExp(path);
                path.params = params;
                
            }
            app.routes.push({
                method,
                path,
                handler
            })
        }
    })
    ...
    return  app;
}
module.exports = createApplication
Copy the code

Directory:


let http = require('http');
let url = require('url');
function createApplication(){
    // If the method is requested and the path is consistent, the callback is executed
    let app = (req,res) = > {
        let reqMethod = req.method.toLowerCase();
        let {pathname} = url.parse(req.url,true);
        let index = 0;
        function next(){
            if(index === app.routes.length){
                res.statusCode = 404;
                res.end(`Cannot ${reqMethod} ${pathname}`);
                return;
            } 
            let {method,path,handler} = app.routes[index++];
            if(method === 'middleware') {/ / middleware
                if(pathname === path || path == '/' || pathname.startsWith(path + '/')){
                    handler(req,res,next)
                }else{
                    next();Execute the next middleware without iteration}}else{
                / / routing
                if(path.params){
                    // Route to path parameter
                    if(path.test(pathname)){
                        let params = {}
                        let values = pathname.match(path).slice(1);
                        values.forEach((value,index) = >{
                            params[path.params[index]] = value
                        });
                        req.params = params; // Mount the parameters to req
                        handler(req,res);
                    }else{ next(); }}else{
                    if((method === reqMethod || method === all)&& (pathname == path|| pathname === The '*')){
                        handler(req,res);
                    }else{
                        next();
                    }
                }
            }
        }
        next();
    }
    app.routes = [];
    // Store method path callback
    let methods = ['get'.'post'.'put'.'delete'.'options'];
    app.use = function(path,handler){
        if(typeofhandler ! ='function'){
            handler = path;
            path = '/'
        }
        app.routes.push({
            method: 'middleware',
            path,
            handler
        })
    }
    app.all = function (path, handler) {
        app.routes.push({
            method: 'all',
            path,
            handler
        })
    }
    methods.forEach(method= > {
        app[method] = (path,handler) = > {
            // Route with path parameters
            let params = [];
            if(path.includes(':')) {// Convert the path to a re if it has:
                path = path.replace(/:([^\/]+)/g.function(){
                    params.push(arguments[1]);
                    return '(/ [^ \] +)';
                })
                path = new RegExp(path);
                path.params = params;
                
            }
            app.routes.push({
                method,
                path,
                handler
            })
        }
    })
    app.listen = (. args) = > {
        letserver = http.createServer(app); server.listen(... args); }return  app;
}
module.exports = createApplication
Copy the code

Middleware – 1

Express has a lot of middleware built in, so the desired methods are already parsed and can be used directly

let express = require('./express');
let app = express();

app.use(function (req,res,next) {... next(); }); app.get('/article', (req,res,next)=> {
  console.log(req.path,req.query);
  res.send({name:'zfpx'});
});
app.listen(3000);

Copy the code

Implement the contents of app.use

test: localhost:3000/article? a=1&b=2

app.use(function (req,res,next) {
    let {path,query} = url.parse(req.url,true);
    req.path = path;
    req.query = query;
    req.hostname = 'XXXX';
    // Decorate mode
    let end = res.end.bind(res);
    res.send = function(value){
        console.log(typeof value);
        if(typeof value === 'object'){
            end(JSON.stringify(value))
        }else if(Buffer.isBuffer(value) || typeof value === 'string'){
            end(value)
        }else{
            end(value.toString())
        }
        
    }
    next();
});
Copy the code

Middleware – 2

Enable a static service

index.js

let express = require('./express');
let app = express();

app.use(function (req,res,next) {... next(); }); app.get('/article', (req,res,next)=> {
  console.log(req.path,req.query);
  res.send({name:'zfpx'});
});
app.listen(3000);

Copy the code

Use the content

let express = require('express');
let app = express();

let path = require('path');
let fs = require('fs')

function static(p){
    return (req ,res ,next) = > {
        let newPath = path.join(p, req.path);
        fs.stat(newPath,(err,stat) => {
             if(err){
                 next();
             }else{
                 console.log(stat.isDirectory());
                 
                 if(stat.isDirectory()){
                     let p = path.join(newPath,'/index.html');
                     console.log(p);
                     
                     fs.createReadStream(p).pipe(res)
                 }else{
                     fs.createReadStream(newPath).pipe(res)
                 }
             }
        })
    }
}

Copy the code