Summary of basic usage of Node18.x
- 1. Node.js modularity
- 2. Package management tools
- 2.1、npm
- 2.2. npm installation
- 2.3. Basic use of npm
- 2.4. Search package
- 2.5. Download the installation package
- 2.6. Production environment and development environment
- 2.7. Production dependence and development dependence
- 2.8. Global installation
- 2.9. Modify windows execution policy
- 2.10. Installation package dependencies
- 2.11. Install the specified version of the package
- 2.12. Delete dependencies
- 2.13. Configure command alias
- 3、cnpm
- 4、yarn
- 5、nvm
- 6. Express framework
Supporting video: Shang Silicon Valley 2023 version Node.js zero-based video tutorial, nodejs novice to master
Supporting code: https://gitee.com/Augenstern-creator/kuang-study-nodejs
1. Node.js modularity
1.1. Module exposure data
- create
me.js
//声明函数
function tiemo(){
console.log('贴膜....');
}
//暴露数据
module.exports = tiemo;
- create
index.js
//导入模块
const tiemo = require('./me.js');
//调用函数
tiemo();
There are two ways for modules to expose data:
module.exports = value
exports.name = value
There are a few points to note when using it:
module.exports
Can expose arbitrary data
1.2. Introduction of modules
Use require in the module to pass in the file path to import the file
//导入模块
const tiemo = require('./me.js');
Some notes on using require:
-
For modules created by yourself, it is recommended to write relative paths when importing , and cannot be omitted
./
and../
-
When importing the node.js built-in module, you can directly require the name of the module without adding
./
and../
-
js
json
You don’t need to write a suffix when importing files . -
If you import other types of files, they will
js
be processed as files -
If the imported path is a folder, the file corresponding to the attribute in the file in the folder will first be detected. If it exists, it will be imported. Otherwise, an error will be reported if the file does not exist. If the main attribute does not exist, or package.json does not exist, it will try to import the and in the folder . If it is still not found, an error will be reported.
package.json
main
index.js
index.json
2. Package management tools
The following is a list of commonly used package management tools on the front end:
- npm
- yarn
- cnpm
2.1、npm
The full name of npm Node Package Manager
, translated into Chinese means Node's package management tool
2.2. npm installation
node.js will automatically install npm during installation, so if you have installed node.js, you can use npm directly. You can npm -v
test it by checking the version number. If the version number is displayed, the installation is successful, otherwise the installation fails.
It is normal for the nodejs version number to be different when checking the version.
2.3. Basic use of npm
Create an empty directory, then use this directory as the working directory to start the command line tool and executenpm init
npm init
The function of the command is to initialize the folder into a package and interactively create the package.json filepackage.json
It is the configuration file of the package. Every package must havepackage.json
Content example:
{
"name": "01_npm",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
translate:
{
"name": "1-npm", #包的名字
"version": "1.0.0", #包的版本
"description": "", #包的描述
"main": "index.js", #包的入口文件
"scripts": {
#脚本配置
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "", #作者
"license": "ISC" #开源证书
}
There are some things to note during the initialization process:
package name
( Package name ) cannot use Chinese characters or capital letters. The default value is the name of the folder, so the folder name cannot use Chinese characters or capital letters.version
( Version number ) requires definition in the form of xxx, x must be a number, and the default value is1.0.0
package.json
Can be created and modified manually- Use
npm init -y
ornpm init --yes
create quicklypackage.json
2.4. Search package
URL search: https://www.npmjs.com/
2.5. Download the installation package
We can install packages through npm install
the and commands, for example we want to use the unqi packagenpm i
# 格式
npm install <包名>
npm i <包名>
# 示例
npm install uniq
npm i uniq
Proceed as follows:
- First, execute
npm init -y
the initialization package npm i uniq
Install uniq package
You can refer to npm's uniq official website instructions for use:
// 1.导入 uniq 包
const uniq = require('uniq');
// 2.使用函数
let arr = [1,2,3,4,5,4,3,2,1];
// [ 1, 2, 3, 4, 5 ]
console.log(uniq(arr));
Here are some points to note:
- Pay attention to changing Taobao source code
npm cache clean --force
Can clear npm cache
After running, two resources will be added to the folder:
node_modules 文件夹
:Storage downloaded packagespackage-lock.json 包的锁文件
: The version used to lock the package
After installing uniq, uniq is a dependent package of the current package , sometimes referred to as dependency.
Thinking: What exactly does require import? The workflow of require is as follows:
- Find the folder with the same name in node_modules under the current folder
- Search for the folder with the same name in node_modules in the upper-level directory until you find the root directory of the disk
2.6. Production environment and development environment
- The development environment is an environment specifically used by programmers to write code. It generally refers to the programmer's computer . Projects in the development environment can generally only be accessed by the programmer himself.
- The production environment is the environment where the project code is officially run. It generally refers to the official server computer . Projects in the production environment are generally accessible to every customer.
2.7. Production dependence and development dependence
We can set options during installation to distinguish the types of dependencies , which are currently divided into two categories:
type | Order | Replenish |
---|---|---|
production dependence | npm i --save uniq npm i -S uniq |
-S is equivalent to --save, -S is the default option. Package information is saved in package.json dependencies property. |
Development dependencies | npm i --save-dev less npm i -D less |
-D is equivalent to --save-dev package information is saved in package.json devDependencies attribute |
Therefore, development dependencies are dependency packages that are only used in the development phase, while production dependencies are dependency packages that are used in both the development phase and the final online operation phase.
Because the uniq and less packages are installed locally and not globally, they can only be used in the 06_npm folder.
2.8. Global installation
We can execute the installation option -g
to install globally
npm i -g nodemon
nodemon
After the global installation is completed, you can run the command anywhere on the command line . The function of this command is to automatically restart the node application.
illustrate:
- Globally installed commands are not affected by the working directory location
npm root -g
You can view the location of the global installation package through- Not all packages are suitable for global installation . Only global tools are suitable. You can determine the installation method by checking the official documentation of the package.
Tips: Solutions to the following problems you may encounter
2.9. Modify windows execution policy
Windows does not allow npm global commands to execute script files by default, so the execution policy needs to be modified.
- Open command line as administrator
powershell
- Key-in
set-ExecutionPolicy remoteSigned
- Type
A
and then hit Enter - If it does not take effect, you can try restarting vscode/webstrom
2.10. Installation package dependencies
A commonly used command in project collaboration is that npm i
you can use this command to install project dependencies based on the dependency declarations of package.json
andpackagelock.json
npm i
npm install
The node_modules folder will not be stored in the repository in most cases.
2.11. Install the specified version of the package
You may encounter version mismatches in the project. Sometimes you need to install a specified version of the package. You can use the following command:
## 格式
npm i <包名@版本号>
## 示例
npm i [email protected]
2.12. Delete dependencies
You may need to delete some unnecessary packages in the project. You can use the following command:
## 局部删除
npm remove uniq
npm r uniq
## 全局删除
npm remove -g nodemon
2.13. Configure command alias
You can execute commands more easily by configuring command aliases: properties package.json
in configurationscripts
{
"scripts": {
"server": "node server.js",
"start": "node index.js",
}
}
After the configuration is complete, you can use the alias to execute the command:
npm run server
npm run start
However, the start alias is special and you can omit run when using it:
npm start
npm start
It is a commonly used command in projects and is generally used to start the project.npm run
It has the feature of automatically searching in the upper directory,require
just like the function- For unfamiliar projects, we can
scripts
refer to some operations of the project by viewing the properties.
3、cnpm
cnpm is a complete mirror built by Taobao npmjs.com
, also called Taobao mirror, website: https://npmmirror.com/
- The cnpm service is deployed on the domestic Alibaba Cloud server, which can improve the download speed of packages.
- The official also provides a global tool package cnpm, and the operation commands are roughly the same as npm.
3.1. Install cnpm
We can install the cnpm tool through npm
npm install -g cnpm --registry=https://registry.npmmirror.com
3.2. Operation commands
Function | Order |
---|---|
initialization | cnpm heat |
Installation package | cnpm i uniq cnpm i -S uniq cnpm i -D uniq cnpm i -g nodemon |
Install project dependencies | cnpm i |
Remove uniq dependency | cnpm r uniq |
3.2. npm configure Taobao image
You can also use Taobao mirror with npm. There are two ways to configure it:
- direct configuration
- Tool configuration
3.2.1. Direct configuration
Execute the following command to complete the configuration:
npm config set registry https://registry.npmmirror.com/
3.2.2. Tool configuration
Use to nrm
configure the mirror address of npmnpm registry manager
- Install nrm
npm i -g nrm
- Modify image
# 查看所有的镜像
nrm ls
# 选择淘宝镜像
nrm use taobao
# 切换到官方地址
nrm use npm
- Check whether the configuration is successful
npm config list
Check whether the registry address is https://registry.npmmirror.com/, if so, it indicates success
- It is recommended to use the second method for mirror configuration, because it will be more convenient to modify later.
- Although cnpm can increase speed, npm can also be accelerated through Taobao mirrors, so the usage rate of npm is still higher than cnpm
4、yarn
yarn is a new Javascript package management tool launched by Facebook in 2016. The official website is: https://yarnpkg.com/
4.1. Yarn installation
We can install yarn using npm
npm i -g yarn
4.2. Yarn common commands
Function | Order |
---|---|
initialization | yarn init / yarn init -y |
Installation package | yarn add uniq production dependency yarn add less --dev development dependency yarn global add nodemon global installation |
Delete package | yarn remove uniq deletes the project dependency package yarn global remove nodemon deletes the package globally |
Install project dependencies | yarn |
Run the command | yarn <alias> # No need to add run |
4.3. Yarn configures Taobao image
You can configure the Taobao image through the following command:
yarn config set registry https://registry.npmmirror.com/
yarn config list
You can view yarn configuration items by
4.4, npm and yarn selection
You can choose based on different scenarios: If the company wants to choose based on the project code, you can determine the project's package management tool by locking the file.
- The lock file of npm is
package-lock.json
- The lock file of yarn is
yarn.lock
5、nvm
The full name of nvm. Node Version Manager
As the name suggests, it is a tool used to manage node versions, making it easy to switch between different versions of Node.js.
5.1. Download and install
- Enter the download address: https://github.com/coreybutler/nvm-windows/releases
- Select
nvm-setup.exe
Download
5.2. Common commands
Order | illustrate |
---|---|
nvm list available | Show all Node.js versions available for download |
nvm list | Show installed versions |
nvm install 18.17.1 | Install version 18.12.1 of Node.js |
nvm install latest | Install the latest version of Node.js |
nvm uninstall 18.17.1 | Remove a certain version of Node.js |
nvm use 18.17.1 | Switch to Node.js 18.12.1 |
Tips: It’s ridiculous. After installing nvm, I get
node -v
an error message andnvm list
it says there is no installed node version. When installing nvm, I was not prompted to manage the installed node version. So here I uninstalled node and installed it first. nvm, then install node 18.17.1 through nvm
- After the installation is complete, find the installation path of nvm - find
settings.txt
the file - configure the download source
root: D:\Develop\nvm
path: D:\Develop\nodejs
node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
- Then open the command line window
# 显示所有可以下载的 Node.js 版本
nvm list available
# 安装 18.12.1 版本的 Node.js
nvm install 18.17.1
- Use this version of node
nvm use 18.17.1
# 查看node版本
node -v
# 查看 npm 版本
npm -v
# 全局安装 nrm
npm i -g nrm
# 查看所有的镜像
nrm ls
# 选择淘宝镜像
nrm use taobao
# 全局安装nodemon
npm i -g nodemon
6. Express framework
express is a minimalist and flexible WEB application development framework based on the Node.js platform. The official website is: Express - a web application development framework based on the Node.js platform - Express Chinese Documentation | Express Chinese Network (expressjs.com.cn)
- To put it simply, express is an encapsulated toolkit that encapsulates many functions to facilitate the development of WEB applications (HTTP services).
6.1. Download and use
- Install via npm
# 先对一个空文件夹进行初始化
npm init -y
# 安装express包
npm i express
# 查看express版本
npm list express
- Create JS file
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 创建路由规则
app.get('/home', (req, res) => {
res.end('hello express server');
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
- Execute the script from the command line
node <文件名>
# 或者
nodemon <文件名>
- Then you can access http://127.0.0.1:3000/home in the browser
6.2, express routing
Routing determines how the application responds to client requests for specific endpoints . A route consists of a request method , a path and a callback function . The usage format is as follows:
app.<method>(path,callback)
Example:
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 创建get路由
app.get('/', (req,res) => {
res.send('首页路由');
});
app.get('/home', (req, res) => {
res.end('home页路由');
});
//创建 post 路由
app.post('/login', (req, res) => {
res.send('登录成功');
});
//匹配所有的请求方法(请求方法无所谓,只要路径是 /test)
app.all('/search', (req, res) => {
res.send('1 秒钟为您找到相关结果约 100,000,000 个');
});
//自定义 404 路由
app.all("*", (req, res) => {
res.send('<h1>404 Not Found</h1>')
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
6.3. Get request parameters
The express framework encapsulates some APIs to facilitate the acquisition of data in request messages, and is compatible with the acquisition methods of the native HTTP module:
- Access:
http://127.0.0.1:3000/request?usernmae=qinxiaolin&age=21
, the following comments are the obtained request parameters
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 获取请求的路由规则
app.get('/request', (req,res) => {
//1. 获取报文的方式与原生 HTTP 获取方式是兼容的
console.log(req.method); // get
console.log(req.url); // /request
console.log(req.httpVersion); // 1.1
console.log(req.headers);
//2. express 独有的获取报文的方式
//获取查询字符串
console.log(req.query); // 『相对重要』 { usernmae: 'qinxiaolin', age: '21' }
// 获取指定的请求头
console.log(req.get('host')); // 127.0.0.1:3000
res.send('请求报文的获取');
});
//自定义 404 路由
app.all("*", (req, res) => {
res.send('<h1>404 Not Found</h1>')
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
6.4. Obtain routing parameters
Routing parameters refer to the parameters in the URL path
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
// 获取路由参数
app.get('/:id.html', (req, res) => {
console.log(req.params.id); // 123
res.send('商品详情' );
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
We visit:
http://127.0.0.1:3000/123.html
,req.params.id
is 123http://127.0.0.1:3000/456.html
,req.params.id
is 456
6.5. Express response settings
The express framework encapsulates some APIs to facilitate data response to clients, and is compatible with the acquisition method of native HTTP modules.
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
// 获取路由参数
app.get('/response', (req, res) => {
//1. express 中设置响应的方式兼容 HTTP 模块的方式
res.statusCode = 404;
res.statusMessage = 'xxx';
res.setHeader('abc','xyz');
res.write('响应体');
res.end('xxx');
//2. express 的响应方法
res.status(500); //设置响应状态码
res.set('xxx','yyy');//设置响应头
res.send('中文响应不乱码');//设置响应体
//连贯操作
res.status(404).set('xxx','yyy').send('你好朋友')
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
Other response methods of express:
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
// 获取路由参数
app.get('/other', (req, res) => {
//跳转响应
//res.redirect('http://atguigu.com')//重定向
下载响应
//res.download(__dirname + './package.json');
//JSON响应
//res.json({
// username : "秦晓",
// age: 21
//});
响应文件内容,把 home.html 响应
res.sendFile(__dirname + '/home.html')
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
-
res.redirect('http://atguigu.com')
Jump response, if accessed,http://127.0.0.1:3000/response
it will jump to http://atguigu.com -
res.download(__dirname + './package.json')
Download the response. If accessed,http://127.0.0.1:3000/response
the package.json file of the project will be downloaded. -
json response to browser
-
Respond
home.html
to the web page to the browser
6.6. express middleware
Middleware is essentially a callback function. The middleware function can be accessed like a routing callback 请求对象(request)
.响应对象(response)
-
中间件
The function is使用函数封装公共操作,简化代码
-
Type of middleware
- global middleware
- routing middleware
6.6.1. Define global middleware
After each request reaches the server, the global middleware function will be executed.
Global middleware is equivalent to the entry gate , and routing middleware is equivalent to the ticket gate.
Enter the station first , then enter the ticket gate
For example, in our code below, when accessing any route, we record the URL and ID and write them to the access.log file:
// 1.导入 express
const express = require('express');
const fs = require('fs');
const path = require('path');
//2. 创建应用对象
const app = express();
// 声明中间件函数(函数名随便写)
// req是请求报文的对象,res是响应报文的对象
function recordMiddleware(req,res,next){
// 获取url 和 id
let {
url,ip} = req;
// 将信息保存在文件的 access.log
// path.resolve() 第一个参数是文件的绝对路径,第二个参数是写入文件的内容
fs.appendFileSync(path.resolve(__dirname,'./access.log'),`${
url} ${
ip}\r\n`);
//调用next(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
next();
}
//使用中间件函数
app.use(recordMiddleware);
//3. 创建路由规则
app.get('/home', (req, res) => {
res.send('前台首页');
});
app.get('/admin', (req, res) => {
res.send('后台首页');
});
app.all('*', (req, res) => {
res.send('<h1>404</h1>>');
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
- Visit in order:
http://127.0.0.1:3000/home
http://127.0.0.1:3000/admin
- ``http://127.0.0.1:3000/1234`
So the steps to define global middleware are as follows:
- Declare middleware functions
function recordMiddleware(req,res,next){
// 实现功能的代码
...
// 执行next函数
next();
}
- application middleware
app.use(recordMiddleware);
// 或者如下写法
app.use(function recordMiddleware(req,res,next){
// 实现功能的代码
...
// 执行next函数
next();
})
6.6.2. Define routing middleware
If you only need to functionally encapsulate certain routes , you will need routing middleware. The calling format is as follows:
app.get('/路径',中间件函数1,中间件函数2,(request,response) => {
})
For example:
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
// 声明中间件函数
let recordMiddleware = (req,res,next) => {
// 判断url中是否code参数等于521,若满足条件,则进行路由回调
if(req.query.code === '521'){
next();
}else{
res.send('暗号错误')
}
}
//使用中间件函数
app.use(recordMiddleware);
//3. 创建路由规则
app.get('/home',recordMiddleware, (req, res) => {
res.send('前台首页');
});
app.get('/admin',recordMiddleware, (req, res) => {
res.send('后台首页');
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
6.6.3. Static resource middleware
express has built-in middleware for processing static resources
// 1.导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
// 静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录
app.use(express.static(__dirname + './public'));
//3. 创建路由规则
app.get('/index.html', (req, res) => {
res.send('前台首页');
});
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
In this way we can access the resource files under public
http://127.0.0.1:3000/css/app.css
http://127.0.0.1:3000/index.html
Precautions:
index.html
The file is a resource that is opened by default
- Access
public/index.html
, both possiblehttp://127.0.0.1:3000/index.html
andhttp://127.0.0.1:3000
- If the static resource matches the routing rule at the same time, the one that matches first will respond.
- If the path rule is one
/
, both routing rules and static resources can match- Routing responds to dynamic resources, and static resource middleware responds to static resources.
6.7. Get the request body
express can use body-parser
the package to process the request body
- Install
npm i body-parser
- Import package
const bodyParser = require('body-parser');
- Get middleware function
- One is the middleware that parses the request body in querystring format.
- The other is middleware that parses the JSON format request body
- Use whichever middleware you need to use
//解析 querystring 格式请求体的中间件
let urlParser = bodyParser.urlencoded({
extended:false}));
//解析 JSON 格式请求体的中间件
let jsonParser = bodyParser.json();
- Set up the routing middleware, and then use
request.body
to get the request body data
// 1.导入 express
const express = require('express');
const bodyParser = require('body-parser');
//2. 创建应用对象
const app = express();
// 声明中间件函数
//解析 querystring 格式请求体的中间件
let urlParser = bodyParser.urlencoded({
extended:false});
//解析 JSON 格式请求体的中间件
let jsonParser = bodyParser.json();
//3. 创建路由规则
// 使用解析 querystring 格式请求体的中间件
app.post('/login',urlParser,(request,response) => {
// 获取请求体数据
console.log(request.body);
// 用户名
console.log(request.body.username);
// 密码
console.log(request.body.password);
response.send('获取请求体数据');
})
//4. 监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000...');
});
6.8、Router
Router in express is a complete middleware and routing system, which can be regarded as a small app object. The role of Router is to modularize routing and better manage routing.
- Create a separate Js file:
homeRouter.js
//1. 导入 express
const express = require('express');
//2. 创建路由器对象
const router = express.Router();
//3. 在 router 对象身上添加路由
router.get('/', (req, res) => {
res.send('首页');
})
router.get('/cart', (req, res) => {
res.send('购物车');
});
//4. 暴露
module.exports = router;
- Referenced in other documents
const express = require('express');
const app = express();
//引入子路由文件
const homeRouter = require('../router/homeRouter');
//设置和使用中间件
app.use(homeRouter);
app.listen(3000,()=>{
console.log('3000 端口启动....');
})
This way you can still visit as before
http://127.0.0.1:3000/cart
6.9. Template engine EJS
- Chinese site: EJS – Embedded JavaScript template engine | EJS Chinese documentation (bootcss.com)
- Official website: EJS – Embedded JavaScript templates
- Download and install EJS
npm i ejs --save
- Import package
// 导入ejs
const ejs = require('ejs');
// 字符串
let china = '中国';
let str = '我爱你 <%= china%>'
// 使用ejs渲染
let result = ejs.render(str,{
china: china});
console.log(result); // 我爱你 中国
6.9.1. Separation usage
// 导入ejs
const ejs = require('ejs');
const fs = require('fs');
// 字符串
let china = '中国';
let str = fs.readFileSync('./00_ejs.html').toString();
// 使用ejs渲染
let result = ejs.render(str,{
china: china});
console.log(result); // 我爱你 中国
Our 00_ejs.html
content is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2> <%= china%> </h2>
</body>
</html>
If you run js like this, it will render
This is how to separate html and js
6.10、express-generator
- Official website: Express application generator - Express Chinese documentation | Express Chinese website (expressjs.com.cn)
- Download Express Application Builder
npx express-generator
- Install dependencies after generating code skeleton
npm i
- Run the project
npm start
- Browser access:
http://127.0.0.1:3000/
6.10.1. Supplementary knowledge
app.use()
You can also set the routing prefix
// 设置路由前缀
app.use('/users', users.js);
// users.js 如下
router.get('/test', function(req, res, next) {
res.send('用户测试');
});
As shown in the above code, due to the addition of /users
prefix, the access url becomeshttp://127.0.0.1:3000/users/test