node.js搭建原生服务器以及构建数据接口

404 阅读5分钟

1.创建空文件夹创建package.json文件(npm init)

{
  "name": "node-server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

2.下载cross-env依赖(npm install --save cross-env)和全局下载nodemon工具(npm install nodemon -g),方便启动项目

3.修改package.json文件如下所示

{
  "name": "node-serve",
  "version": "1.0.0",
  "main": "bin/www.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js",
    "prd": "cross-env NODE_ENV=production nodemon ./bin/www.js"
  },
  "repository": {},
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "cross-env": "^7.0.3"
  }
}

4.项目根目录下新建bin文件夹,bin文件夹下创建www.js文件如下所示

const http = require('http')

const PORT = 8888
// 引入服务器处理的回调函数app.js
const serverHandle = require('../app')
// 创建server服务
const server = http.createServer(serverHandle)
// 监听8888端口
server.listen(PORT)

5.服务器处理模块--回调函数app.js

// 引入路由文件
//1.数据的增删改查路由(api)
const handleCurdRouter = require('./src/router/curd');
//2.用户的登录,登出路由(api)
const handleUserRouter = require('./src/router/user');

// 引入处理get请求中的参数模块querystring 
const querystring = require('querystring');

// 基于promise用于处理post请求中的参数
const getPostData = (req) => {
    const promise = new Promise((resolve, reject) => {
        // 非post请求返回空数据
        if (req.method !== 'POST') {
            resolve({})
            return
        }
        // 请求的content-type不是json的返回空数据
        if (req.headers['content-type'] !== 'application/json') {
            resolve({})
            return
        }
        // 请求是post的返回postData
        let postData = ''
        // 监听data方法,处理post数据流
        req.on('data', chunk => {
            postData += chunk.toString()
        })
        // 监听end方法,返回postData
        req.on('end', () => {
            if (!postData) {
                resolve({})
                return
            }
            resolve(
                JSON.parse(postData)
            )
        })
    })
    return promise
}

// 服务器处理方法
const serverHandle = (req, res) => {
    // 设置返回的格式 json
    res.setHeader('Content-Type', 'application/json')
    // 获取请求的路径
    const url = req.url
    // 获取接口路径
    req.path = url.split('?')[0]

    // 解析query,获取get请求参数
    req.query = querystring.parse(url.split('?')[1])
    // 解析postData,获取post请求参数
    getPostData(req).then(postData => {
        req.body = postData
        
        // 处理 增删改查  路由,将req请求数据和res响应数据传入路由模块
        // 经过路由模块的处理获取到返回的数据
        const blogData = handleCurdRouter (req, res)
        if (blogData) {
            res.end(
                JSON.stringify(blogData)
            )
            return
        }
        // 处理 用户登录登出 路由
        // 经过路由模块的处理获取到返回的数据
        const userData = handleUserRouter(req, res)
        if (userData) {
            res.end(
                JSON.stringify(userData)
            )
            return
        }
        // 没有匹配到任何路由时返回404
        // 404路由
        res.writeHead(404, { 'content-type': "text/plain" })
        res.write('404 not found\n')
        res.end('404')
    })
}
//导出服务器处理的函数
module.exports = serverHandle

6.项目根目录新建src文件夹,src下新建router文件夹(拆分所有的路由模块)

处理路由文件,按照请求接口路径进行路由分配,此模块不关心数据的结构和内容

1.router下新建用户登录登出路由user.js

/ 用户登录登出路由文件
// 处理路由文件,按照请求接口路径进行路由分配,此模块不关心数据的结构和内容

// 引入此路由获取数据的方法
const {loginHand,loginOutHand} = require('../cortoller/user')

// 引入返回数据的格式
const {SuccessModel,ErrorModel} = require('../model/dataModel')

// 处理路由的逻辑
const handleUserRouter = (req,res)=>{
    // 获取接口请求方式
    const method = req.method

    // 用户登录接口
    if(method === 'POST' && req.path === '/api/test/user/login'){
        const {username,password} = req.body
        const data = loginHand(username,password)
        if(data.code === 0 ){
            return new SuccessModel(data)
        }else{
            return new ErrorModel('登录失败')
        }
    }

    // 用户登出接口
    if(method === 'GET' && req.path ==='/api/test/user/logout'){
        const data = loginOutHand()
        if(data.code === 0){
            return new SuccessModel(data)
        }else{
            return new ErrorModel('登出失败')
        }
    }
}

module.exports = handleUserRouter

2.router下新建业务增删改查模块curd.js

const {
    getList,
    getDetails,
    addData,
    updateData,
    deleteData
} = require('../cortoller/curd')
const {SuccessModel,errorModel} = require('../model/dataModel')
// 业务数据路由文件
const handleCurdRouter = (req,res)=>{
    const method = req.method
    const id = req.query.id
    // 获取数据列表
    if(method === 'GET' && req.path ==='/api/test/curd/list'){
        const name= req.query.name|| ''
        const keywords = req.query.keywords || ''
        const listData = getList(name,keywords)
        return new SuccessModel(listData,'成功')
    }

    // 获取数据详情
    if(method === 'GET' && req.path ==='/api/test/curd/detail'){
        const data = getDetails(id)
        return new SuccessModel(data)
    }

    // 新增数据
    if(method === 'POST' && req.path ==='/api/test/curd/add'){
        const addData = req.body
        const data = addData(addData )
        return new SuccessModel(data)
    }
    // 更新博客
    if(method === 'POST' && req.path ==='/api/test/curd/update'){
        const data = updateData(id,req.body)
        if(data){
            return new SuccessModel(data)
        }else{
            return new ErrorModel('更新失败')
        }
    }
     // 删除博客
     if(method === 'DELETE' && req.path ==='/api/test/curd/del'){
        const data = deleteData(id)
        if(data.code){
            return new SuccessModel(data)
        }else{
            return new ErrorModel('删除失败')
        }
    }
}

module.exports = handleCurdRouter 

7.src下新建controller文件夹(拆分所有的数据处理模块)

处理请求数据的模块,只关心返回的数据和格式,不关心数据发送给哪个请求

以下数据为假数据,没有连接数据库

1.controller下新建用户登录登出数据模块user.js

// 1.登录接口,参数是用户名和密码
const loginHand = (username,password) => {
    // 查询数据库,用户名和密码是否正确
    if(username === 'wdm' && password === '123456'){
        return {
            code:0,
            msg: '登录成功',
            token:'123456789'
        }
    }
    return {
        code:1,
        msg: '用户名或密码错误',
    }
}

// 登出接口
const loginOutHand = () => {
    return {
        code:0,
        msg: '登出成功',
    }
}
module.exports = {
    loginHand,loginOutHand
}

2.controller下新建业务增删改查数据模块curd.js

// 处理请求数据的模块,只关心返回的数据和格式,不关心数据发送给哪个请求

// 1.获取数据列表,请求参数为keywords
const getList = (name, keywords) => {
    // name和keywords是数据请求参数,通过请求参数进行数据库查询返回数据
    // 返回数据
    return [
        {
            id:1,
            xx:xx,
            xx:xx
        },
        {
            id:2,
            xx:xx,
            xx:xx
        },
        {
            id:3,
            xx:xx,
            xx:xx
        }
    ]
}

// 2.获取数据详情数据,请求参数为id
const getDetails = (id) => {
    // 先返回假数据
    return {
        xx:xx,
        xx:xx
    }
}

// 3.新增数据的请求,请求参数是新增的内容
const addData= (blogData = {}) => {
    // 先返回假数据
    return {
        id:6,
        obj:{}
    }
}

// 4.更新数据的请求,请求参数是id和更新的内容
const updateData= (id,data= {}) => {
    return {
        flags:true,
        id:id,
        obj:{...data}
    }
}

// 5.删除数据的请求,请求参数是数据id
const deleteData= (id) => {
    return {
        id:id,
        msg: '删除成功',
        code:true
    }
}
// 导出所有的方法
module.exports = {
    getList,
    getDetails,
    addData,
    updateData,
    deleteData
}

8.src下新建dataModel文件夹(对返回数据格式和内容进行规范处理模块)

// 设置返回数据的规范

class DataModel {
    constructor(data,message){
        if(typeof data === 'string'){
            this.message = data;
            data = null;
            message = null;
        }
        if(data){
            this.data = data;
        }
        if(message){
            this.message = message;
        }
    }
}

//请求成功时返回格式

class SuccessModel extends DataModel {
    constructor(data,message){
        super(data,message)
        this.code = 0
    }
}

//请求失败时返回格式

class ErrorModel extends DataModel {
    constructor(data,message){
        super(data,message)
        this.code = -1
    }
}

module.exports ={
    SuccessModel,
    ErrorModel
}

9.项目文件结构

  •  node-server
  •         1.bin
  •                 1.1 www.js
  •         2.app.js
  •         3.src
  •                  3.1 controller
  •                         3.1.1  user.js
  •                         3.1.2  curd.js
  •                   3.2  router
  •                         3.2.1  user.js
  •                         3.2.2  curd.js
  •                   3.3  model
  •                         3.3.1  dataModel.js
  •         4.package.json

10.启动项目  npm run dev