当前位置:网站首页>Express (I) - easy to get started

Express (I) - easy to get started

2022-06-26 10:22:00 Red blue purple

Express( One ) —— Simple introduction

background : Participated in the youth training camp project , Use Express To implement the backend , Individuals are assigned to the back end . therefore , Simple quick pass Express. End of project , Go back and write down your notes , Settle down .

Personal blog :Express( One ) —— Simple introduction

Express Is based on Node.js platform , Fast 、 to open up 、 minimalist Web Development framework .

You can install before you start Postman, Very easy to use. Interface testing tool .

1. Hello World

First , install express To project npm i express

then , Start the code world .

// 1.  load express
const express = require('express');

// 2.  call express() obtain .express() The function is express modular ​​ Exported top-level functions 
const app = express();

// 3.  Set the processing function corresponding to the request . In the following example , When the client uses GET Method request / The handler function is called when 
app.get('/', (req, res) => {
    
  res.send('Hello World!');
})

// 4.  start-up web service 
app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

Last , Command line execution nodemon app.js or node app.js.nodemon Support hot update .

image-20220207151828081

2. route

Routing refers to how a server-side application responds to client requests from a specific endpoint . By a URI( Path signs ) And a specific HTTP Method (GET、POST etc. ) Composed of .

Definition structure of route :

app.METHOD(PATH, HANDLER);
  • app:express example
  • METHOD: It's a HTTP Request method
  • PATH: Server path
  • HANDLER: The processing function executed when the route matches . Parameters :request and response Object handles request and response data separately
const express = require('express');

const app = express();

app.get('/', (req, res) => {
    	// GET request 
  res.send('Hello World!');
})

app.post('/', (req, res) => {
    	// POST request 
  res.send('post /');
})

app.put('/user', (req, res) => {
    	// PUT request 
  res.send('put user');
})

app.delete('/user', (req, res) => {
    	 // DELETE request 
  res.send('delete user');
})

app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

image-20220207161937956

2.1 Request object

req The object represents HTTP request .

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    
  console.log(" Request address : ", req.url);
  console.log(" Request method : ", req.method);
  console.log(" Request header : ", req.headers);
  console.log(" Request parameters : ", req.query);

  res.end();  //  End response . If not , The client will be waiting for a response 
})

app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

postman Test use :http://localhost:8080/?name=clz

image-20220207162928596

2.2 The response object

res Object represents the receipt of HTTP Sent after request HTTP Respond to .

2.2.1 Status code and status information

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    

  res.statusCode = 404;   //  Set response status code 
  res.statusMessage = "test";    //  Set response status information . Here's the test , In theory 404 It should correspond Not Found, This makes sense 

  res.end();  //  End response 
})

app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

image-20220207163814050

2.2.2 Send multi segment text

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    
  res.write('hello ');
  res.write('world');   // res.write() Just send data , Still need res.end() To end the response 

  // res.end('hello world'); //  End sending data at the same time 

  res.end();  //  End response 
})

app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

image-20220207165808608

2.2.3 cookie

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    
  res.cookie('name', 'clz');  //  Set up cookie

  res.end();  //  End response 
})

app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

image-20220207164941307

2.3 Routing path

You can use regular expression syntax

//  Match the root path 
app.get("/", function(req, res) {
    
  res.send("root");		
});

//  matching /abc
app.get("/abc", function(req, res) {
    
  res.send("abc");		
});

//  matching /test.text
app.get("/test.text", function(req, res) {
    
  res.send("test.text");		
});



//  matching /acd、/abcd
app.get("/ab?cd", function(req, res) {
    
  res.send("ab?cd");
});

//  matching /abcd、/abxxxxcd
app.get("/ab*cd", function(req, res) {
    
  res.send("ab?cd");
});

//  matching /abe、/abcde
app.get("/ab(cd)?e", function(req, res) {
    
  res.send("ab?cd");
});

//  Match all contains a
app.get(/a/, function(req, res) {
    
  res.send("/a/");
});

//  Match with fly At the end of the , Include /test.fly,/test/aaa/fly etc. 
app.get(/.*fly$/, function(req, res) {
    
  res.send("/.*fly$/");
});

2.4 Dynamic path

app.get("/users/:userId/books/:bookId", function(req, res) {
    
  res.send(req.params);
});


//  Limit dynamic parameters 
app.get("/:a(\\d+)", function (req, res) {
    	
  res.send(req.params);
});

image-20220210123301562

3. Case study

Create a simple CRUD Interface services . increase (Create)、 Read query (Retrieve)、 to update (Update) And delete (Delete)

  • Query the task list :GET /todos
  • according to ID Query a single task :GET /todos/:id
  • Add tasks :POST /todos
  • Modify task :PATCH /todos
  • Delete task :DELETE /todos/:id

3.1 Routing design

const express = require('express');

const app = express();


app.get('/todos', (req, res) => {
    
  res.send(' Query the task list ');
})

app.get('/todos/:id', (req, res) => {
    
  res.send(` according to ID Query a single task , id yes ${
      req.params.id}`);   //  adopt req.params.id To get dynamic path parameters id
})

app.post('/todos', (req, res) => {
    
  res.send(' Add tasks ');
})

app.patch('/todos/:id', (req, res) => {
    
  res.send(` Modify task , id yes ${
      req.params.id}`);
})

app.delete('/todos/:id', (req, res) => {
    
  res.send(` Delete task , id yes ${
      req.params.id}`);
})


app.listen(8080, () => {
    
  console.log('http://localhost:8080/');
})

image-20220207172638141

3.2 Get task list

Data files db.json

{
    
  "todos": [
    {
    
      "id": 1,
      "title": "express"
    },
    {
    
      "id": 2,
      "title": " note "
    },
    {
    
      "id": 3,
      "title": " Update blog "
    }
  ]
}
app.get('/todos', (req, res) => {
    
  fs.readFile('./db.json', 'utf8', (err, data) => {
    
    if (err) {
    
      return res.status(500).json({
      // res.json() Specially send json Formatted data , No json The format will report an error 
        error: err.message
      })
    }

    const db = JSON.parse(data);    //  Convert a string to JSON object 
    res.status(200).json(db.todos);
  })
})

image-20220207184102851

3.3 according to ID Query a single task

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);
    const todo = db.todos.find(todo => todo.id === Number.parseInt(req.params.id));   // url The dynamic parameters in are strings 

    if (!todo) {
        //  Mission id non-existent 
      return res.status(404).end();   //  need return Prevent code from going on , Otherwise, both sending... Will occur 404 Send again 200
    }

    res.status(200).json(todo);
  })
})

image-20220208231000242

3.4 encapsulation db modular

As you can see from the code above , The logic of reading data files is the same , That is, it can be encapsulated into a separate module db.js

db.js

const fs = require('fs');
const {
     promisify } = require('util');  //  hold callback Form of asynchrony api Turn it into promise Formal 
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)
}

After the encapsulation app.js( The following routes have not changed )

const express = require('express');

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

const app = express();


app.get('/todos', async (req, res) => {
    
  try {
       //  The necessity of handling exceptions : If no exception is thrown , May be waiting for a response 
    const db = await getDb();   //  because getDb yes async Of , So all forms will be encapsulated into Promise, Therefore, data acquisition should await
    res.status(200).json(db.todos);   // // res.json() Specially send json Formatted data , No json The format will report an error 
  } 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 === Number.parseInt(req.params.id));   // url The dynamic parameters in are strings 

    if (!todo) {
        //  Mission id non-existent 
      return res.status(404).end();   //  need return Prevent code from going on , Otherwise, both sending... Will occur 404 Send again 200
    }

    res.status(200).json(todo);
  } catch (err) {
    
    res.status(500).json({
    
      error: err.message
    })
  }
})

3.5 Add tasks

app.post('/todos', (req, res) => {
    
  // 1.  Get client request body parameters 
  console.log(req.body);

  res.end();
})

then , You will find something terrible

image-20220208231856994

that , At this time, you need to configure the form request body to solve the above problem

app.use(express.json())   //  Configure parsing form request body :application/json. take json Format to js object 

image-20220208232402601

perfect !!!( However , Not at all )

image-20220208233059259

Put it another way , It's time to change the soup . because express.json() Can only parse json Formal

app.use(express.urlencoded())   //  Configure parsing form request body :application/x-www-form-urlencoded

then , Because it needs to be saved to db.json in , So it should also be in db.js To encapsulate a saveDb() Method (app.js Naturally, we should also introduce saveDb, This part can't come out )

db.js

const fs = require('fs');
const {
     promisify } = require('util');  //  hold callback Form of asynchrony api Turn it into promise Formal 
const path = require('path');

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

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

exports.getDb = async () => {
    
  const data = await readFile(dbPath, 'utf8');

  return JSON.parse(data)
}

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

Add the code part of the task

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

    // 2.  data validation 
    if (!todo.title) {
    
      return res.status(422).json({
    
        error: 'The field title is required.'
      })
    }

    // 3.  After data validation , Store data in db.json in 
    const db = await getDb();
    const lastTodo = db.todos[db.todos.length - 1];   //  Get the last todo

    todo.id = lastTodo ? lastTodo.id + 1 : 1;   //  If one todo None , Then add todo Of id yes 1
    db.todos.push(todo)

    await saveDb(db);

    // 4.  Send a response 
    res.status(200).json(todo);
  } catch (err) {
    
    res.status(500).json({
    
      error: err.message
    })
  }
})

image-20220208235418267

Small optimization : It can be found that , After adding tasks ,db.json Ugly format . It's just a way of JavaScript Object to JSON String problem , So all you need to do is JSON.stringify() Just work hard .

JSON.stringify()

exports.saveDb = async db => {
    
  const data = JSON.stringify(db, null, ' ');    //  The third argument here is two spaces , Is to indent by two spaces 
  await writeFile(dbPath, data)
}

image-20220209000445369

Sharp eyed students may find , Added tasks id It is different from the previous position . that , I have a little obsessive-compulsive disorder. Naturally, I still have to master micro operation .

image-20220209001337659

finally ...

image-20220209001401680

3.6 Modify task

app.patch('/todos/:id', async (req, res) => {
    
  try {
    
    // 1.  Get client request body parameters 
    const todo = req.body;

    // 2.  Find the... To be modified todo
    const db = await getDb();
    const ret = db.todos.find(todo => todo.id === Number.parseInt(req.params.id))

    if (!ret) {
       //  Something to change todo non-existent 
      return res.status(404).end();
    }

    Object.assign(ret, todo)    //  Return an object . If you add todo There are inherent attributes in , Then modify the attribute value . without , Add a new attribute 

    await saveDb(db);
    res.status(200).json(ret);

  } catch (err) {
    
    res.status(500).json({
    
      error: err.message
    })
  }
})

Modify the original properties :

image-20220209003447970

New properties

image-20220209003636418

3.7 Delete task

app.delete('/todos/:id', async (req, res) => {
    
  try {
    
    const todoId = Number.parseInt(req.params.id);
    const db = await getDb();

    const index = db.todos.findIndex(todo => todo.id === todoId);   //  Create a to delete todo The index of 

    if (index === -1) {
       //  To delete todo Not at all 
      return res.status(404).end();
    }

    db.todos.splice(index, 1);
    await saveDb(db);
    res.status(200).end()

  } catch (err) {
    
    res.status(500).json({
    
      error: err.message
    })
  }
})

image-20220209004455315

4. res.end() and res.send() difference

Official statement :

  • res.end() End response processing flow .( however , You can also send a response at the end )

  • res.send() Send various types of responses .

4.1 res.end()

End the response process . Used to quickly end the response without any data .

  • Parameters can be buffer object 、 character string
  • Only accept server response data , If it is Chinese, it will be garbled

4.2 res.send()

send out HTTP Respond to .

  • Parameters can be buffer object 、 character string 、 object 、 Array
  • When sending to the server , More headers will be sent automatically , Include Content-Type: text/html;charset=utf-8, So Chinese won't be garbled

res.send() Send object response

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    
  res.send({
    
    name: 'clz'
  })
})

app.listen(3000, () => {
    
  console.log('http://localhost:3000/');
})

image-20220209213846401

Instead of using res.end() send out

image-20220209214613515

res.send() Send Chinese ( Use a browser to view ,postman The response header may be set automatically )

res.send(" test ")

image-20220209215019228

Change it to res.edn()

image-20220209215053732

Learn the reference video :

Node.js Series of tutorials Express

原网站

版权声明
本文为[Red blue purple]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202170543390579.html