Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

A: hi! ~ Hello, everyone, I am YK bacteria 🐷, a front-end microsystem ✨, like to share their small knowledge 🏹, welcome to follow me 😘 ~ [wechat account: YK2012YK2012, wechat official account: ykyk2012]

Node.js is a node.js backend framework. Express is a node.js backend framework. Express is a node.js backend framework

1. Start

Reference video tutorial: 2021 latest and most full Express tutorial (basic + combat + principle), B station is the best, no one

1.1 document

www.expressjs.com.cn/

1.2 installation

npm i express
Copy the code

Install the interface test tool Postmanwww.postman.com/downloads/

1.3 Hello World

Create the app.js file

const express = require("express");

const app = express();
const port = 3000 / / the default 3000

app.get("/".(req, res) = > {
  res.send("Hello World");
});

app.listen(3000.() = > {
  console.log(`Server running at http://localhost:${port}/ `);
});
Copy the code

Run the app. Js

Open the web page

You can start the program using Nodemon

This can detect file changes, automatic update procedures

Postman interface test

2. Routing basis

Routing refers to determining that an application responds to a client’s request for a specific endpoint, which is a URI and a specific HTTP request method (GET/POST, etc.). Each route can have one or more handler functions that are executed when the route is matched

The route definition takes the following structure

app.METHOD(path, handle)
Copy the code
  • appExpress instance
  • METHODLowercase HTTP request method
  • pathRouting path on the server
  • handleA handler that is executed when a route matches

More routing related www.expressjs.com.cn/guide/routi…

demo

  1. Response ‘Hello World’ in the root path
app.get('/'.(req, res) = > {
  res.send('Hello World')})Copy the code

  1. Respond to the POST request at the root path
app.post('/'.(req, res) = > {
  res.send('Got a POST request')})Copy the code

  1. Respond to a PUT request to the /user path
app.put("/user".(req, res) = > {
  res.send("Got a POST request at /user");
});
Copy the code

  1. Respond to a DELETE request to the /user path
app.delete("/user".(req, res) = > {
  res.send("Got a DELETE request at /user");
});
Copy the code

3. Request and response

The Express application uses request and Response objects, parameters of the routing callback function, to process request and response data

app.get('/'.(request, response) = >{
	// ...
})
Copy the code

Express does not secondary abstract the existing features of Node.js, but merely extends the basic functionality required for Web applications on top of it

  • The HTTP module is still used internally
  • The request object inherits fromhttp.IncomingMessage
  • The response object inherits fromhttp.ServerResponse

Express extends request and response objects in HTTP modules

3.1 Request Object Request

API

Node. Js nodejs.org/dist/latest…

Express www.expressjs.com.cn/4x/api.html…

The Request object represents an HTTP request and has properties such as the request query string, parameters, body, HTTP label, and so on

app.get("/".(request, res) = > {
  console.log("request.url:", request.url);
  console.log("request.method:", request.method);
  console.log("request.headers:", request.headers);
  console.log('Request parameters:', request.query)
  res.send("Hello World");
});
Copy the code

Postman sends the request

Console output

3.2 Response Object Response

Node. Js nodejs.org/dist/latest…

Express www.expressjs.com.cn/4x/api.html…

app.get("/".(request, response) = > {
  // Set the response status code
  // response.statusCode = 201

  // response.write('a')
  // response.write('b')
  // response.write('c')

  // End the response
  // response.end()
  // response.end('efg')

  // response.send("Hello World");
  // response.send({
  // name: 'yk'
  // })
  response.cookie('yk'.'kk')
  response.status(201).send('OK')});Copy the code

3.3 case

Use this example to create a simple CRUD interface service to master the basic usage of Express

Requirement: Implement CRUD interface service to task list

  • Query task List
    • GET /todos
  • Query a task based on its ID
    • GET /todos/:id
  • Add tasks
    • POST /todos
  • Modify the task
    • PATCH /todos
  • Delete the task
    • DELETE /todos/:id

Start by creating a file db.json to store the data

{
  "todos": [{"id": 1."title": "Eat"
    },
    {
      "id": 2."title": "Sleep"
    },
    {
      "id": 3."title": "Write code"}}]Copy the code

GET Query task list

app.get("/todos".(req, res) = > {
  fs.readFile("./db.json"."utf8".(err, data) = > {
    if (err) {
      return res.status(500).json({
        error: err.message,
      });
    }
    const db = JSON.parse(data);
    res.status(200).json(db.todos);
  });
});
Copy the code

test

GET Queries a task based on its ID

app.get("/todos/:id".(req, res) = > {
  fs.readFile("./db.json"."utf8".(err, data) = > {
    if (err) {
      return res.status(500).json({
        error: err.message,
      });
    }
    const db = JSON.parse(data);
    // console.log(typeof req.params.id) // string
    const todo = db.todos.find((todo) = > todo.id === +req.params.id);
    if(! todo) {return res.status(404).end();
    }
    res.status(200).json(todo);
  });
});
Copy the code

test

Optimization: Encapsulate data read operations

Create a db. Js

const fs = require("fs");
const { promisify } = require("util");
const path = require("path");

const readFile = promisify(fs.readFile);

const dbPath = path.join(__dirname, "./db.json");

exports.getDb = async() = > {const data = await readFile(dbPath, "utf8");
  return JSON.parse(data);
};
Copy the code

Optimized GET requests

const { getDb } = require("./db");

app.get("/todos".async (req, res) => {
  try {
    const db = await getDb();
    res.status(200).json(db.todos);
  } catch (err) {
    res.status(500).json({
      error: err.message, }); }}); app.get("/todos/:id".async (req, res) => {
  try {
    const db = await getDb();
    const todo = db.todos.find((todo) = > todo.id === +req.params.id);
    if(! todo) {return res.status(404).end();
    }
    res.status(200).json(todo);
  } catch (err) {
    res.status(500).json({
      error: err.message, }); }});Copy the code

POST Add task

In the db. Js

Encapsulate the saveDb method for saving files

const writeFile = promisify(fs.writeFile);

exports.saveDb = async (db) => {
  const data = JSON.stringify(db, null."");
  await writeFile(dbPath,data);
};
Copy the code

In the app. In js

【 Middleware 】

Configure the parse form request body: application/json

app.use(express.json());
Copy the code

Configure parse form request body: Applicatioin/X-www-form-urlencoded

app.use(express.urlencoded());
Copy the code

The complete code

app.post("/todos".async (req, res) => {
  try {
    // 1. Obtain the client request body parameters
    const todo = req.body;

    // 2. Data validation
    if(! todo.title) {return res.status(422).json({
        error: "The filed title is required."}); }// 3. The data is verified and stored in db
    const db = await getDb();
    const lastTodo = db.todos[db.todos.length - 1];
    todo.id = lastTodo ? lastTodo.id + 1 : 1;
    db.todos.push(todo);
    await saveDb(db);

    // 4. Send response
    res.status(201).json(todo);
  } catch (err) {
    res.status(500).json({
      error: err.message, }); }});Copy the code

test

Db. Json file updated

PATCH Modification Task

app.patch("/todos/:id".async (req, res) => {
  try {
    // 1. Get form data
    const todo = req.body;
    // 2. Find the task item to be modified
    const db = await getDb();
    const result = db.todos.find((todo) = > todo.id === +req.params.id);
    if(! result) {return res.status(404).end();
    }
    // 3. Merge objects
    Object.assign(result, todo);
    await saveDb(db);
    // 4. Send response
    res.status(200).json(result);
  } catch (err) {
    res.status(500).json({
      error: err.message, }); }});Copy the code

DELETE DELETE task

app.delete("/todos/:id".async (req, res) => {
  try {
    const db = await getDb();
    const index = db.todos.findIndex((todo) = > todo.id === +req.params.id);
    if (index === -1) {
      return res.status(404).end();
    }
    db.todos.splice(index, 1);
    await saveDb(db);
    res.status(204).end();
  } catch (err) {
    res.status(500).json({
      error: err.message, }); }});Copy the code

test

4. Route details

4.1 Routing Method

The routing method is derived from one of the HTTP methods and is attached to an instance of the Express class

The following code is an example of a route to the application root defined for the GET and POST methods

app.get('/'.(req, res) = > {
  res.send('GET request to the homeage')
})
app.post('/'.(req, res) = > {
  res.send('POST request to the homeage')})Copy the code

Express supports methods that correspond to all HTTP request methods: GET, POST, etc. For a complete list, please see www.expressjs.com.cn/4x/api.html…

There is also a special routing method, app.all(), used to load middleware functionality for the path of all HTTP request methods. Whether you use GET, POST, PUT, DELETE, or any other HTTP request method supported by the HTTP module, the following handlers are performed on the routed request

app.all('/'.(req, res) = > {
  console.log("all Method");
  next();
})
Copy the code

4.2 Routing Path

The routing path, in combination with the request method, defines the endpoint to which the request can be made.

The routing path can be string, String Pattern, or regular expression.

Son of? , +, *, and () are the corresponding subsets of their regular expressions.

Hyphen – and dot. Interpreted by string-based path literals

If you need $to use the dollar character in the path string, pass it ([enclosed in and])

For example /data/$book the path string used for the request would be /data/([\s])book

Express uses path-to-regexp to match routing paths. See the regular expression paths documentation for all the possibilities for defining routing paths

Express Route Tester, while not supporting pattern matching, is a convenient tool for testing basic Express routes

The query string is not part of the routing path

Example of routing paths based on [string]

  1. This route path matches the request to the root route /
app.get('/'.(req, res) = > {
  res.send('root');
})
Copy the code
  1. This routing path matches the request to /about
app.get('/about'.(req, res) = > {
  res.send('about');
})
Copy the code
  1. This route path matches the request to /random.text
app.get('/random.text'.(req, res) = > {
  res.send('random.text');
})
Copy the code

Example of routing paths based on string pattern

  1. This routing path matches requests to/ACd and /abcd
app.get('/ab? cd'.(req, res) = > {
  res.send('ab? cd');
})
Copy the code
  1. This route matches requests to /abcd, /abbcd, and /abbbcd
app.get('/ab+cd'.(req, res) = > {
  res.send('ab+cd');
})
Copy the code
  1. This route path matches requests to /abcd, /abxcd, /ab123cd, /abRANDOMcd, etc
app.get('/ab*cd'.(req, res) = > {
  res.send('ab*cd');
})
Copy the code
  1. This routing path matches requests to/Abe, /abcde
app.get('/ab(cd)? e'.(req, res) = > {
  res.send('ab(cd)? e');
})
Copy the code

Example of routing paths based on regular expressions

  1. This routing path matches the request to anything with an ‘a’ in it
app.get(/a/.(req, res) = > {
  res.send('/a/');
})
Copy the code
  1. This routing path matches the request to the content at the end of fly
app.get(/.*fly$/.(req, res) = > {
  res.send('/.*fly$/');
})
Copy the code

4.3 Path Parameters

The route parameter is named the URL segment to capture the value specified at its location in the URL and the captured value is filled into the req.params object with the name of the route parameter specified in the path as its respective key

Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: {"userId": "34"."bookId": "8989"}
Copy the code

To define a route using route parameters, simply specify the route parameters in the route path

app.get('/users/:userId/books/:bookId'.(req, res) = > {
  res.send(req.params);
})
Copy the code

The path parameter name must consist of A literal character ([A-zA-z0-9_]) due to A hyphen – and A dot. Are interpreted literally, so they can be used with routing parameters

Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: {"from": "LAX"."to": "SFO"}
Copy the code
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: {"genus": "Prunus"."species": "persica"}
Copy the code

For better control over the exact string that can be matched by the route argument, you can append a regular expression to the parentheses ()

Route path: /user/:userId(\\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}
Copy the code

4.4 Route Handlers

You can provide multiple callback functions that behave like middleware to handle requests. The only exception is that these callbacks may call next(‘route ‘) to bypass the rest of the route callbacks. You can use this mechanism to impose preconditions on routes and then pass control to subsequent routes if there is no reason to continue using the current route. Routing handlers can take the form of functions, arrays of functions, or a combination of both, as shown in the following examples. A single callback function can handle routing.

app.get('/users/a'.(req, res) = > {
  res.send('Hello A');
})
Copy the code

Multiple callback functions can handle the same route (be sure to specify the next object)

app.get('/users/b'.(req, res) = > {
  console.log('Hello')
  next()
}, (req, res) = > {
  res.send('Hello B');
})
Copy the code

An array of callback functions can handle routing

function logOriginalUrl(req, res, next) {
  console.log("Request URL", req.originalUrl);
  next();
}
function logMethod(req, res, next) {
  console.log("Requset Type", req.method);
  next();
}
const logStuff = [logOriginalUrl, logMethod];

app.get("/user/:id", logStuff, (req, res, next) = > {
  res.send("User Info");
});
Copy the code

A combination of individual functions and function arrays can handle routing

4.5 Response Method

The method on the response object () in the table below res sends the response to the client and terminates the request-response cycle. If these methods are not called from the route handler, the client request is suspended.

methods describe
res.download() The file prompted to download
res.end() End the response
res.json() Sending a JSON response
res.jsonp() Send a JSON response with JSONP support
res.redirect() Redirect request
res.render() Render View template
res.send() Send various types of responses
res.sendFile() Send the file as an octet stream
res.sendStatus() Sets the response status code and sends its string representation as the response body

4.6 app. The route ()

You can use app.route() to create a linkable route handler for routing paths. Because paths are specified in a single location, it is helpful to create modular routes, as well as to reduce redundancy and typos. For more information about routing, see the: Router() documentation.

This is an example of app.route() using the defined chained route handler.

app.route('/book')
.get((req, res) = >{
  res.send('Get a random book')
})
.post((req, res) = >{
  res.send('Add a book')
})
.put((req, res) = >{
  res.send('Update the book')})Copy the code

Refer to video 2021 latest and most full Express tutorial (basic + combat + principle), B station is the best, no one