preface
As front-end engineers, we often want to break the dimensional wall of the front-end (not just to write pages and make interfaces hot), want to learn a back-end language, build our own services, and rush towards the full stack direction. So in my opinion, there is no better choice for us than Node.js. Node.js does not require us to learn a new language, but its ideas if learners do not have some OS, network, database related knowledge, is also a little understanding.
Interest as a driver, let’s first build our own services, write our own Restful interface to find confidence, and then go to further study it!
The official website describes Express as follows:
Based on node. js platform, fast, open, minimalist Web development framework
Although the sparrow is small and has all the five organs, it retains the flexible Node.js development framework of the smallest scale. So let’s play it together today and build our own service.
PS: The first and second sections will not describe too much of the original things, all the principles we put in the third section to realize their own
Express
More on that
The installation
If you want to do a good job, you must first sharpen your tools. Let’s install what we have before we develop it. The builder tool is available on the website to quickly build the project, and the generated project already contains all the necessary dependencies.
npm install -g express-generator
Copy the code
Once installed, you can initialize an Express application.
express express-app
Copy the code
Project Catalog
Express - app │ app. Js │ package. The json │ ├ ─ bin │ WWW │ ├ ─ public │ ├ ─ images │ ├ ─ javascripts │ └ ─ stylesheets │ style.css. CSS │ ├─routes │ ├.js │ users.js │ ├─ exercises errorCopy the code
app.js
Application initialization files include importing all application dependencies, setting the view template engine, static resource paths, importing routes, and configuring middlewarebin/www
Start file, set listening port, starthttp
Service etc.public
Static file directoryroutes
Routing file that responds to the userhttp
Request and return the resultviews
View files
Interface development
Before we start development, let’s run through the code that comes with the project.
Hello Express
Start the program
cd bin
node www
Copy the code
PS: in the WWW inside the definition of the following, default does not change the program at 3000 port
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
Copy the code
After starting localhost:3000, you can see the welcome page.
Start the process
- First of all,
Node.js
Launched thehttp
The server Express
Route distribution is implemented internally, and is distributed to specific routes according to routing methods and pathscontroller
In theaction
logic- The input
localhost:3000
So the route is ‘/’ atapp.js
There are two lines of code inapp.use('/', indexRouter); app.use('/users', usersRouter); Copy the code
This corresponds to the registration of the routing group, and the final match is
routes/index.js
The method insiderouter.get('/'.function(req, res, next) { res.render('index', { title: 'Express' }); }); Copy the code
- A static page is rendered inside the route
index
“And passed in the template variableextends layout block content h1= title p Welcome to #{title} Copy the code
This corresponds to the welcome page you see.
Connecting to a Database
Before development, you still have to create a new database, and MySQL is used in this article. Install the MySQL driver.
npm install mysql --save
Copy the code
Create a DB folder under the root directory. The directory structure is as follows
Db │ dbconfig. js │ index.jsCopy the code
Index.js is our own ORM class. The following MySQL operations will be based on it, so if you are interested, you can add a DB class to Node.js
Write MySQL configuration to dbconfig.js
module.exports = {
mysql: {
host: 'localhost'.user: 'root'.password: '* * * * * *'.database: 'express_test'.port: 3306}};Copy the code
Next, create a database
CREATE DATABASE IF NOT EXISTS express_test;
Copy the code
Let’s create a user table
USE express_test;
CREATE TABLE IF NOT EXISTS user (
u_id INT PRIMARY KEY AUTO_INCREMENT,
u_account VARCHAR(100) NOT NULL,
u_password VARCHAR(100) NOT NULL
);
Copy the code
Add the following code to app.js
const Db = require('./db/index')
global.Db = new Db.Orm();
Copy the code
Restful API development
With the above preparations in place, we are ready for our interface development. We developed two interfaces, login interface and registration interface. The parameters of the login interface and registration interface are as follows
parameter | Will choose | type | instructions |
---|---|---|---|
account | true | string | The user name |
password | true | string | password |
Registered interface
Add the following code to routes/user.js:
- To obtain
account
、password
parameter - Do some validation on the parameters
- Whether the user already exists
- Check whether data is successfully inserted
function validate(account, password) {
if(! account) {return {
status: false.msg: 'User name cannot be empty'}}if(! password) {return {
status: false.msg: 'Password cannot be empty'}}if (account.length > 24) {
return {
status: false.msg: 'Username cannot be larger than 24 characters'}}if (password.length > 24) {
return {
status: false.msg: 'Password must be no more than 24 characters'}}return {
status: true.msg: null
}
}
router.post('/register'.async (req, res, next) => {
const {
account,
password
} = req.body
let userValidate = validate(account, password),
result, user
if(! userValidate.status) { res.end(userValidate.msg)return
}
let result
try {
result = await Db.table('user').where('u_account', account).count()
} catch (error) {
throw new Error(error)
}
if (result > 0) {
res.end('The username already exists')
return
} else {
let data = {
u_account: account,
u_password: md5(password)
}
let user
try {
user = await Db.table('user').insert(data)
} catch (error) {
throw new Error(error)
}
if (user.affectedRows > 0) {
res.json({
msg: 'Registration successful'.status: true})}else {
res.end('error'); }}})Copy the code
Comes with an MD5 implementation of Node.js
function md5(data) {
var Buffer = require("buffer").Buffer;
var buf = new Buffer.from(data);
var str = buf.toString("binary");
var crypto = require("crypto");
return crypto.createHash("md5WithRSAEncryption").update(str).digest("hex");
}
Copy the code
Login interface
After implementing the registration interface, let’s implement the login interface. Add the following code to routes/users.js:
- Get parameters and verify
- According to the user incoming
account
Go to query md5
User password after comparison- The login state after login is discussed in section 2
router.post('/login'.async (req, res, next) => {
const {
account,
password
} = req.body
let userValidate = validate(account, password),
result, dbPassword
if(! userValidate.status) { res.end(userValidate.msg)return
}
try {
result = await Db.table('user').where('u_account', account).find();
} catch (error) {
throw new Error(error)
}
dbPassword = result.length > 0 ? result[0].u_password : null
if (dbPassword === md5(password)) {
res.json({
msg: 'Successful landing'.status: true})}else {
res.json({
msg: 'Please check username or password'.status: false})}})Copy the code
Upload a file
Uploading files is also a common function in the development of the interface. Next, we use Node to implement a file uploading function. Here we use a middleware called Multer. Multer is a Node.js middleware that processes form data of type multipart/form-data. It is mainly used for uploading files. NPM install multer –save Add the following route to routes/users.js:
- Using the
multer
After that, the file information is placedreq.files
inside - Based on the
Promise
Encapsulates a method for uploading a single file - And then use
Promise.all
Unified Management - If an error occurs while reading or writing a file, the processing here is
resolve(err)
Rather thanreject(err)
To ensurePromise.all
Call successful, as for the upload failed error message, on the front show it ~
var multer = require('multer');
var fs = require('fs')
var upload = multer({
dest: '.. /public/upload_tmp/'
});
router.post('/upload', upload.any(), (req, res) = > {
let files = [...req.files],
pros = []
files.forEach(file= > pros.push(uploadSingleFile(file)))
Promise.all(pros).then(uploadFiles= > {
res.json(uploadFiles)
}).catch(err= > {
res.json(err)
})
})
function uploadSingleFile(file) {
return new Promise((resolve, reject) = > {
fs.readFile(file.path, (err, data) = > {
if (err) {
resolve(err)
} else {
let timestamp = +new Date(a)let path = `.. /public/images/${timestamp}-${file.originalname}`
fs.writeFile(path, data, err= > {
if (err) {
resolve(err)
} else {
resolve({
originalname: file.originalname,
filename: `${timestamp}-${file.originalname}`})}})})})})}Copy the code
Accessing a static file
Express also implements static file access logic. App. use(express.static(path.join(__dirname, ‘public’)));
All we need to know is the name of the file and enter the following browser address:
http://localhost:3000/images/xxx.png
Copy the code
To access the files we uploaded ~
PM2
PM2 is a node process management tool, which simplifies many node application management tasks, such as performance monitoring, automatic restart, and load balancing. Common commands are as follows:
$pm2 start app.js - I 4 # cluster mode to start 4 app.js application instances # 4 applications will automatically load balance $pm2 start app.js App.js --name=" API "# Start the application and name it" API "$pm2 start app.js --watch # Automatically restart the application when the file changes $pm2 start script.sh # Start bash script $ $pm2 show [app-name] # display the CPU usage of each application $pm2 logs # $pm2 logs [app-name] # Flush $pm2 stop all # flush $pm2 stop all # flush $pm2 stop 0 $pm2 reload all $pm2 gracefulReload all # Graceful reload all apps in Cluster mode Cluster mode $pm2 delete all # delete all applications $pm2 delete 0 # delete application ID 0 $pm2 scale API 10 # $pm2 save # Save the list of applications. $pm2 update # Reloads the list of saved applications Save processes, kill PM2 and restore processes $ pm2 generate # Generate a sample json configuration file pm2 start app.js --node-args="--max-old-space-size=1024"Copy the code
After the pm2 is installed, we can start with pm2 start WWW -i Max
nodemon
During development, the code needs to be restarted frequently, which is very tedious. We can use the tool Nodemon, which is used to monitor the changes of the code file and automatically restart the code when it changes.
npm install -g nodemon
nodemon www
Copy the code
The last
Personally, the leap from front end to back end is not only a linguistic difference, but also a grammatical difference that can be quickly made up for. The lack of more is the design of the database, the processing of background logic, the processing of resources and other thinking. Only with this article, throw out a brick to attract jade, the road ahead is long, I will search up and down.
Thank you for reading, if you like, you can help to click a “like” yo ~