当前位置:网站首页>01. Project introduction of blog development project
01. Project introduction of blog development project
2022-07-06 05:22:00 【John is orange】
The preliminary development of the blog project
1. Project introduction
1.1 The goal is
- Develop a blog system , It has the basic function of blog
- Only develop server End , Don't care about the front end
1.2 demand
- home page , Author URI , Blog details page
- The login page
- Management Center , new page , Edit page
1.3 Technical solution
data storage
Blog
user
The password needs to be encrypted
How to connect with the front end , Interface design
About logging in
There are unified solutions in the industry , Generally, there is no need to redesign
It's more complicated to implement
2. Development interface
2.1 http Request overview
- DNS analysis , resume TCP Connect , send out http request (http Default port 80,https Default port 443)
- server Received http request , Handle , And back to
- The client receives the returned data , Processing data ( Such as rendering the page , perform js)
2.2 Handle get request
- get request , That is, the client wants to server End access data , Such as querying the blog list
- adopt querystring To transfer data , Such as a.html?a=100&b=200
- Browser direct access , Is sent get request
Sample code
const http = require("http");
const {
emitWarning } = require("process");
const qs = require("qs");
const server = http.createServer((req, res) => {
console.log(req.method); // GET
const url = req.url; // Get the complete of the request url
console.log(url);
req.query = qs.parse(url.split("?")[1]); // qs analysis query by JS object
res.end(JSON.stringify(req.query)); // Message sending completed
});
server.listen(8000, () => {
console.log("listen on 8000");
});
Run input http://localhost:8000/?a=100&b=erere after , Background output :
listen on 8000
GET
/?a=100&b=erere
GET
/favicon.ico
/favicon.ico The browser will send it automatically GET request .
Browser display results :
2.3 Handle post request
- post request , That is, the client should transfer data to the server , Such as creating a new blog
- adopt post data To transfer data
- Browsers cannot directly simulate , Handwriting required js, Or use postman
Sample code
const http = require("http");
const server = http.createServer((req, res) => {
if (req.method === "POST") {
// The requested data format
console.log("content-type", req.headers["content-type"]);
// receive data
let postData = "";
// Receiving data streams ,req Triggered when sending data
req.on("data", (chunk) => {
postData += chunk.toString();
});
// req Triggered when transmission is complete
req.on("end", () => {
console.log(postData);
res.end("hello world"); // Back here , Because it's asynchronous
});
}
});
server.listen(8000, () => {
console.log("listen on port 8000");
});
use postman Send request results :
Client received hello world
The backend receives the data sent by the client , And we know that the data type sent by the server is JSON
2.4 Comprehensive case
const http = require("http");
const qs = require("qs");
const server = http.createServer((req, res) => {
const method = req.method;
const url = req.url;
const path = url.split("?")[0];
const query = qs.parse(url.split("?")[1]);
// Set the return format to JSON
res.setHeader("content-type", "application/json");
// Returned data
const resData = {
method,
url,
path,
query,
};
// return
if (method === "GET") {
// return JSON Format string
res.end(JSON.stringify(resData));
}
if (method === "POST") {
let postData = "";
req.on("data", (chunk) => {
postData += chunk.toString();
});
req.on("end", () => {
resData.postData = postData;
res.end(JSON.stringify(resData));
});
}
});
server.listen(8000, () => {
console.log("listen on port 8000");
});
GET Return results :
POST Return results :
3. Build development environment
- from 0 Begin to build , Don't use any framework
- Use nodemon Monitoring file changes , Automatic restart node
- Use cross-env Set the environment variable
3.1 build
yarn init -y
node Project initializationgit init
initialization Git WarehouseInstall the required third-party libraries
yarn add nodemon cross-env --dev
stay
package.json
Written in scripts, Simplify input command line instructions"scripts": { "dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js" },
After writing like this , In the command line
yarn dev
perhapsnpm run dev
You can execute the above command instead .cross-env NODE_ENV=dev
The current environment is the development environment , And one variable is NODE_ENV The value is dev.js Documents can be passed throughprocess.env.NODE_ENV
To get to the dev.nodemon ./bin/www.js
nodemon monitor www.js The change of , Each change is automatically executed again .( Because I have customized the main entry as www.js)
3.2 Code test build effect
stay ./bin/www.js Write the following code in :
const http = require("http"); const { serverHandle } = require("../app"); const PORT = 8000; // The callback after creating the server is placed in app.js In the document const server = http.createServer(serverHandle); // stay 8000 Listening on the port server.listen(PORT);
stay app.js The file contains the callback to create the server ,app.js Focus on business code .
const serverHandle = (req, res) => { // Set the return format JSON res.setHeader("Content-type", "application/json"); const resData = { name: "sjh", site: "ssjjhh.com", env: process.env.NODE_ENV, }; res.end(JSON.stringify(resData)); }; module.exports = { serverHandle, };
perform
yarn dev
, Visit the local 8000 port , You can get the... Returned by the server JSON data .
4. Initialize route
4.1 Development interface
- Initialize route : According to the design of the previous counting scheme , Make a route
- Return false data : Separate routing and data processing , It has complied with the design principles
By viewing the route , It can be found that interfaces are divided into two categories :blog and user. Six interfaces can be implemented through two files .
blog route
Getting through first is the most important , Write each interface first , The returned content is ignored .
const handleBlogRouter = (req, res) => {
const method = req.method;
// Get a list of blogs
if (method === "GET" && req.path === "/api/blog/list") {
return {
msg: " This is the interface to get the blog list ",
};
}
// Get blog details
if (method === "GET" && req.path === "/api/blog/detail") {
return {
msg: " This is the interface to get blog details ",
};
}
// Create a new blog
if (method === "POST" && req.path === "/api/blog/new") {
return {
msg: " This is the interface for creating a new blog ",
};
}
// Update a blog
if (method === "POST" && req.path === "/api/blog/update") {
return {
msg: " This is the interface for updating blog ",
};
}
// Delete a blog
if (method === "POST" && req.path === "/api/blog/del") {
return {
msg: " This is the interface for deleting blogs ",
};
}
};
module.exports = {
handleBlogRouter,
};
user route
user Routing is the same
const handleUserRouter = (req, res) => {
const method = req.method;
// Sign in
if (method === "POST" && req.path === "/api/user/login") {
return {
msg: " This is the user login interface ",
};
}
};
module.exports = {
handleUserRouter,
};
app.js Incoming routing
Introduce two routes app.js, And after analysis path and query after , Pass to routing . If the requested path and route can match , Will return data , Otherwise do not return .
Significance lies in , Separate business functions , Improve maintainability .
According to this principle , If the routes do not match , Namely 404 Not found . stay serverHandle At the end 404 To deal with .
const qs = require("qs");
const {
handleBlogRouter } = require("./src/router/blog");
const {
handleUserRouter } = require("./src/router/user");
const serverHandle = (req, res) => {
// Set the return format JSON
res.setHeader("Content-type", "application/json");
// obtain path
const url = req.url;
req.path = url.split("?")[0];
// analysis query
req.query = qs.parse(req.path)
// Handle blog route
const blogData = handleBlogRouter(req, res);
if (blogData) {
res.end(JSON.stringify(blogData));
// Need to be return, Otherwise, it will continue to execute
return;
}
// Handle user route
const userData = handleUserRouter(req, res);
if (userData) {
res.end(JSON.stringify(userData));
return;
}
// Missed route : Plain text returns 404 Information
res.writeHead(404, {
"content-type": "text/plain" });
res.write("404 not found");
res.end();
};
module.exports = {
serverHandle,
};
Unify the return information of success and failure
establish model Folder , Create success and failure models :
// src/model/resModel.js
class BaseModel {
constructor(data, message) {
// data It can be the object , It could be a string
if (typeof data === "string") {
this.message = data;
data = null;
message = null;
}
if (data) {
this.data = data;
}
if (message) {
this.message = message;
}
}
}
/** * The model of successful information */
class SuccessModel extends BaseModel {
constructor(data, message) {
super(data, message);
this.errno = 0;
}
}
/** * Model of failure information */
class ErrorModel extends BaseModel {
constructor(data, message) {
super(data, message);
this.errno = -1;
}
}
module.exports = {
SuccessModel,
ErrorModel,
};
Return information later , After the processing of the model , Back to json The structure is expected to be as follows :
{
"errno": 0,
"data": {
...},
"message": "xxx"
}
4.2 Blog list routing development
Now build one controller layer , Write relevant business inside . Because the database is not connected yet , So first return the data you made . The following is the relevant code for obtaining blog list data :
// src/controller/blog.js
const getList = (author, keyword) => {
// return Mock data ( The format is correct )
return [
{
id: 1,
title: " title A",
content: " Content A",
createTime: 1654087871762,
author: "zhangsan",
},
{
id: 2,
title: " title B",
content: " Content B",
createTime: 1654087879762,
author: "lisi",
},
];
};
controller Split the data ,router Only focus on data . The following is the related code of blog list routing :
// src/router/blog.js
// Get a list of blogs
if (method === "GET" && req.path === "/api/blog/list") {
const author = req.query.author || "";
const keyword = req.query.keyword || "";
const listData = getList(author, keyword);
return new SuccessModel(listData);
}
Return results :
4.3 Blog details routing development
// src/router/blog.js
// Get blog details
if (method === "GET" && req.path === "/api/blog/detail") {
const id = req.query.id;
const data = getDetail(id);
return new SuccessModel(data);
}
controller And the return result is slightly .
4.4 Processing of route development POST data
app.js Now there is only parsing path and query,POST data did not .POST Data transmission is asynchronous , Wait deliberately POST After data transmission , The relevant code of the route can run , Make sure you get it POST data.
Because of convenience , Create a single Handle POST data Function of . Asynchronous method returns promise after , have access to then/catch Monogram or await Syntax sugar to handle asynchronous requests , Just run the following code .
// app.js
const getPostData = (req) => {
return new Promise((resolve, reject) => {
// Not POST The request does not exist POST data The problem of
if (req.method !== "POST") {
resolve({
});
return;
}
// If POST data No JSON Formatted data , Direct to ignore ( This project POST data All are JSON Format )
if (req.headers["content-type"] !== "application/json") {
resolve({
});
return;
}
let postData = "";
req.on("data", (chunk) => {
postData += chunk.toString();
});
req.on("end", () => {
if (!postData) {
resolve({
});
return;
}
resolve(JSON.parse(postData));
});
});
};
const serverHandle = async (req, res) => {
// Set the return format JSON
res.setHeader("Content-type", "application/json");
// obtain path
const url = req.url;
req.path = url.split("?")[0];
// analysis query
req.query = qs.parse(req.path);
// analysis POST data Put it after req.body Inside
const postData = await getPostData(req);
req.body = postData;
// Handle blog route
const blogData = handleBlogRouter(req, res);
if (blogData) {
res.end(JSON.stringify(blogData));
// Need to be return, Otherwise, it will continue to execute
return;
}
// Handle user route
const userData = handleUserRouter(req, res);
if (userData) {
res.end(JSON.stringify(userData));
return;
}
// Missed route : Plain text returns 404 Information
res.writeHead(404, {
"content-type": "text/plain" });
res.write("404 not found");
res.end();
};
4.5 New blog route development
With the top postData After processing , The route can go through req.body
Get post The transmitted data .
// router/blog.js
// Create a new blog
if (method === "POST" && req.path === "/api/blog/new") {
const data = newBlog(req.body);
return new SuccessModel(data);
}
// controller/blog.js
const newBlog = (blogData = {
}) => {
// blogData Is a blog object , contain title、content attribute
return {
...blogData, // Just a demonstration. POST data Succeeded in getting
id: 3, // Indicates a new blog , Inserted into the data table id
};
};
stay postman send out post Request and response results :
4.6 Update blog routing development
Update route is also used post Method , But what is different from the new blog is , When updating a blog, you need to bring id Parameters can be modified .
// controller/blog.js
/** * Updates the specified id The blog content of * @param {number} id To update the corresponding blog id * @param {object} blogData Blog object , contain title、content attribute */
const updateBlog = (id, blogData = {
}) => {
console.log("update blog", blogData);
return true;
};
// router/blog.js
// Update a blog
if (method === "POST" && req.path === "/api/blog/update") {
const result = updateBlog(id, req.body);
if (result) {
return new SuccessModel();
} else {
return new ErrorModel(" Update failed ");
}
}
4.7 Delete blog route
// controller/blog.js
const delBlog = (id) => {
return true;
};
// router/blog.js
// Delete a blog
if (method === "POST" && req.path === "/api/blog/del") {
const result = delBlog(id);
if (result) {
return new SuccessModel();
} else {
return new ErrorModel(" Failed to delete blog ");
}
}
4.8 Login routing completed
// controller/user.js
const loginCheck = (username, password) => {
// Use fake data first
if (username === "admin" && password === "123456") {
return true;
}
return false;
};
module.exports = {
loginCheck
};
// router/user.js
const {
loginCheck } = require("../controller/user");
const {
SuccessModel, ErrorModel } = require("../model/resModel");
const handleUserRouter = (req, res) => {
const method = req.method;
// Sign in
if (method === "POST" && req.path === "/api/user/login") {
const {
username, password } = req.body;
const result = loginCheck(username, password);
if (result) {
return new SuccessModel();
}
return new ErrorModel(" Login failed ");
}
};
module.exports = {
handleUserRouter,
};
4.9 Routing and API The difference between
- API: Front end and backing , A term for docking between different ends
- url ( route ), Input , Output
- route :
- API Part of , Address of the interface
- A definition inside the backend system
边栏推荐
- Hometown 20 years later (primary school exercises)
- GAMES202-WebGL中shader的编译和连接(了解向)
- Fuzzy -- basic application method of AFL
- js Array 列表 实战使用总结
- Microblogging hot search stock selection strategy
- Nacos - TC Construction of High available seata (02)
- 指針經典筆試題
- 02. Develop data storage of blog project
- Zoom and pan image in Photoshop 2022
- Knowledge points of circular structure
猜你喜欢
04. 项目博客之日志
Postman manage test cases
Postman assertion
Modbus协议通信异常
Vulhub vulnerability recurrence 73_ Webmin
Compilation et connexion de shader dans games202 - webgl (comprendre la direction)
Summary of deep learning tuning tricks
Zoom and pan image in Photoshop 2022
Codeforces Round #804 (Div. 2) Editorial(A-B)
Vulhub vulnerability recurrence 72_ uWSGI
随机推荐
Can the feelings of Xi'an version of "Coca Cola" and Bingfeng beverage rush for IPO continue?
无代码六月大事件|2022无代码探索者大会即将召开;AI增强型无代码工具推出...
idea一键导包
Codeforces Round #804 (Div. 2) Editorial(A-B)
flutter 实现一个有加载动画的按钮(loadingButton)
Summary of redis basic knowledge points
MySQL advanced learning summary 9: create index, delete index, descending index, and hide index
pix2pix:使用条件对抗网络的图像到图像转换
Some common skills on unity inspector are generally used for editor extension or others
03. 开发博客项目之登录
自建DNS服务器,客户端打开网页慢,解决办法
Qt TCP 分包粘包的解决方法
JDBC calls the stored procedure with call and reports an error
【华为机试真题详解】检查是否存在满足条件的数字组合
Three.js学习-光照和阴影(了解向)
Postman manage test cases
Using stopwatch to count code time
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
2022半年总结
SQLite add index