express设计的基于json restful API(一)

791 阅读2分钟

文章主要记录如何实现使用express连接数据库,做增删改查,关联数据库,封装路由,jsonwebtoken鉴权,bcrypt登录密码加密,multer文件上传和一些请求数据的处理,开发日志记录。

1建立node服务器

1.1 server.js
const http = require('http');
const app = require('./app');


const port = process.env.PORT || 3000;

const server = http.createServer(app);

server.listen(port);
1.2 app.js
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.status(200).json({
    message: '请求3000成功'
  })
})

module.exports = app;
1.3 package.json
{
  "name": "node_restful_api",
  "version": "1.0.0",
  "description": "build a restful api with node.js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cloudXA/build_restful_api.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/cloudXA/build_restful_api/issues"
  },
  "homepage": "https://github.com/cloudXA/build_restful_api#readme",
  "devDependencies": {
    "express": "^4.17.1",
    "mongoose": "^5.9.20",
    "nodemon": "^2.0.4"
  }
}

使用以下命令行,打开端口localhost:3000

npm install

2 解决跨域问题,增加产品路由、订单路由

2.1 app.js
const express = require('express');
const app = express();
// 在本地可以查看请求连接的信息
const morgan = require('morgan');
// 解析请求体request body
const bodyParser = require('body-parser');

// 分别引入产品product、订单order路由
const productRoutes = require('./api/routes/products');
const ordersRouter = require('./api/routes/orders')

// express中间层代码,实现请求日志打印,请求体解析
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// 借助Access-Control-Allow-Origin实现跨域,也可指定特定的域名地址
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Access, Authorization"
  );
  if (req.method === 'OPTIONS') {
    res.header('Acess-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE,GET');
    return res.status(200).json({});
  }
  next();
})

// Routes which should handle requests 
// 用于处理路由中转
app.use('/products', productRoutes)
app.use('/orders', ordersRouter)

module.exports = app;
2.2 package.json
{
  "name": "node_restful_api",
  "version": "1.0.0",
  "description": "build a restful api with node.js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cloudXA/build_restful_api.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/cloudXA/build_restful_api/issues"
  },
  "homepage": "https://github.com/cloudXA/build_restful_api#readme",
  "devDependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mongoose": "^5.9.20",
    "morgan": "^1.10.0"
  }
}

2.3 api路由代码
2.3.1 api/routes/products.js
  • 基于json的增删改查
const express = require('express');
const router = express.Router();

router.get('/', (req, res, next) => {
  res.status(200).json({
    message: 'handling get request to /products'
  })
})

router.post('/', (req, res, next) => {
  const product = {
    name: req.body.name,
    price: req.body.price
  }
  res.status(201).json({
    message: 'handling post request to /products',
    createdProduct: product
  })
})

router.get('/:productId', (req, res, next) => {
  const id = req.params.productId;
  if(id === 'special') {
    res.status(200).json({
      message: 'you discovered the special id',
      id: id
    })
  } else {
    res.status(200).json({
      message: 'you passed an Id'
    })
  }
})

router.patch('/:productId', (req, res, next) => {
  res.status(200).json({
    message: 'update product'
  })
})

router.delete('/:productId', (req, res, next) => {
  res.status(200).json({
    message: 'delete producte'
  })
})

module.exports = router;

2.3.2 api/routes/products.js
  • 也是基于json的增删改查
const express = require('express');
const router = express.Router();

// Handle incoming  GET request to /orders 
// 处理连入到/orders的GET请求
router.get('/', (req, res, next) => {
  res.status(200).json({
    message: 'Orders were fetched'
  })
})

router.post('/', (req, res, next) => {
  const order = {
    productId: req.body.productId,
    quatity: req.body.quatity
  }
  res.status(201).json({
    message: 'Order was created',
    order: order
  })
})

router.get('/:orderId', (req, res, next) => {
  res.status(200).json({
    message: 'Order was created',
    orderId: req.params.orderId
  })
})

module.exports = router;


项目当前结构 图1.1