根据json配置文件生成restful风格的后台接口服务

今天看到json-parser,正好想复习一下node的知识,做了个实现。
用到的包就两个,express和body-parser。
package.json

{
  "name": "json-server2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1"
  }
}

db.json
其中的每一个key为url的路径,value为返回值。

{
	"posts": [
		{
			"id": 1,
			"title": "json-server",
			"author": "typicode"
		},
		{
			"id": 2,
			"title": "json-server2",
			"author": "typicode2"
		}
	],
	"comments": [
		{
			"id": 1,
			"body": "some comment",
			"postId": 1
		}
	],
	"profile": {
		"name": "typicode"
	}
}

index.js
入口文件

const express = require('express');
const {dbJson} = require('./fileOperate');
const home = 'http://localhost:3000/';
const bodyParser = require('body-parser');
const {homePageHandler,restlessHandler,getRestful,postRestful,putRestful,deleteRestful} = require("./appHandler");

const app = express();
/**
 * 设置bodyParser
 */
app.use(bodyParser.json({limit:'1mb'}));
app.use(bodyParser.urlencoded({extend:true}));
/**
 * 设置全局跨域响应头
 */
app.all('*',function(req,res,next){
    res.header('Access-Control-Allow-Origin', '*');//的允许所有域名的端口请求(跨域解决)
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    res.header('Access-Control-Allow-Methods', '*');
    next();
});

/**
 * 遍历json数据生成对应风格的接口
 */
Object.entries(dbJson).forEach(entry => {
    let key = entry[0];
    let targetArr = entry[1];
    console.log(home+key);
    /**
     * 普通风格get
     */
    app.get('/'+key,(req,res) => {
        restlessHandler(req,res,targetArr);
    });
    /**
     * rest风格get
     */
    app.get('/'+key+'/:id',(req,res) => {
        getRestful(req,res,targetArr);
    });
    /**
     * rest风格post
     */
    app.post('/'+key,(req,res)=>{
        postRestful(req,res,targetArr);
    });
    /**
     * rest风格post
     */
    app.put('/'+key+'/:id',(req,res)=>{
        putRestful(req,res,targetArr);
    });
    /**
     * rest风格delete
     */
    app.delete('/'+key+'/:id',(req,res)=>{
        deleteRestful(req,res,targetArr);
    });
});

console.log('Resources');
//请求主页
app.get('/',(req,res) => {
    homePageHandler(req,res);
});

//主页请求数据
app.get('/data',(req,res) => {
    res.json(dbJson);
});

//默认监听3000端口
app.listen(3000,()=>{
    console.log('\nHome');
    console.log(home);
});



appHandler.js
处理各种请求

const { writeToDb,readHomePage,dbJson} = require('./fileOperate');

/**
 * 根据id查找对象
 * @param arr
 * @param resp
 * @param id
 */
function getResponseObjById(arr,resp,id) {
    const obj = arr.find(o => o.id === id);
    if(obj) {
        resp.send(obj);
    }else {
        resp.status(500).send('没找着呢亲,再看一眼db.json');
    }
}
/**
 * 主页处理
 * @param req
 * @param res
 */
function homePageHandler(req,res) {
    res.set({'Content-Type':'text/html'});
    const content = readHomePage();
    res.send(content);
}
/**
 * 普通风格get处理
 * @param req
 * @param res
 * @param targetArr
 */
function restlessHandler(req,res,targetArr) {
    if(req.query.id) {
        getResponseObjById(targetArr,res,parseInt(req.query.id));
    }else {
        res.json(targetArr);
    }
}
/**
 * get风格处理
 * @param req
 * @param res
 * @param targetArr
 */
function getRestful(req,res,targetArr) {
    getResponseObjById(targetArr,res,parseInt(req.params.id));
}

/**
 * post风格处理
 * @param req
 * @param res
 * @param targetArr
 */
function postRestful(req,res,targetArr) {
    //找到数组最后一个对象
    let lastObj = targetArr[targetArr.length -1];
    //请求参数对象
    const obj = req.body;
    //id +1
    obj.id = lastObj.id+1;
    //新增对象
    targetArr.push(obj);
    writeToDb(dbJson);
    res.json(obj);
}

/**
 * put风格处理
 * @param req
 * @param res
 * @param targetArr
 */
function putRestful(req,res,targetArr) {
    //从url参数中获取id
    const id = parseInt(req.params.id);
    //根据id找到对应的对象
    let targetObj = targetArr.find(item => item.id === id);
    if(targetObj) {
        Object.keys(req.body).forEach(objKey => {
            //更新属性值
            targetObj[objKey] = req.body[objKey];
        });
        writeToDb(dbJson);
        res.json(targetObj);
    }else {
        res.send('没有找到id为'+id+'的对象');
    }
}

/**
 * delete风格处理
 * @param req
 * @param res
 * @param targetArr
 */
function deleteRestful(req,res,targetArr) {
    //从url参数中获取id
    const id = parseInt(req.params.id);
    //根据id找到对应的对象索引值
    let index = targetArr.findIndex(item => item.id === id);
    if(index === -1) {
        res.send('不存在的哦');
    }else {
        //删除对象
        targetArr.splice(index,1);
        writeToDb(dbJson);
        res.json({});
    }
}

module.exports = {homePageHandler,restlessHandler,getRestful,postRestful,putRestful,deleteRestful};

fileOperate.js
封装各种文件操作

const fs = require('fs');

/**
 * 从db文件中读取json数据
 * @returns {object}
 */
function readFromDb() {
    let buffer = fs.readFileSync('./db.json','utf-8');
    return JSON.parse(buffer.toString());
}

/**
 * 将json数据写入到db文件中
 * @param jsonData
 */
function writeToDb(jsonData) {
    fs.writeFileSync('./db.json',
        JSON.stringify(jsonData,null,'\t'));
}

/**
 * 读取主页
 * @returns {string}
 */
function readHomePage() {
    let buffer = fs.readFileSync('./index.html');
    return buffer.toString();
}

module.exports = {dbJson: readFromDb(), writeToDb,readHomePage};

index.html
默认主页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="urls">
        <h1>Resources</h1>
    </div>
    <script>

        (function() {
            let home = 'http://localhost:3000/';
            let urls = document.querySelector('#urls');
            fetch(home+'data').then(res=> {
                return res.json();
            }).then(dbObj => {
                console.log(dbObj);
                Object.entries(dbObj).forEach(entry => {
                    let divElement = document.createElement('div');
                    let aElement = document.createElement('a');
                    aElement.setAttribute('href',home+entry[0]);
                    aElement.textContent = '/'+entry[0];
                    divElement.appendChild(aElement);
                    urls.appendChild(divElement);
                })
            })
        })();

    </script>
</body>
</html>

demo.html
axios测试页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Axios测试页面</title>
</head>
<body>
    <div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DELETE请求</button>
    </div>
    <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
<script>
    function testGet() {
        axios.get('http://localhost:3000/posts?id=1').then(response=> {
            console.log('/posts get',response.data);
        })
    }
    function testPost() {
        axios.post('http://localhost:3000/posts',{"title": "json-server3", "author": "typicode3" }).then(response=> {
            console.log('/posts post',response.data);
        })
    }
    function testPut() {
        axios.put('http://localhost:3000/posts/3',{"title": "json-server...", "author": "typicode..." }).then(response=> {
            console.log('/posts put',response.data);
        })
    }
    function testDelete() {
        axios.delete('http://localhost:3000/posts/3').then(response=> {
            console.log('/posts delete',response.data);
        })
    }
</script>
</body>
</html>

启动时控制台输出
在这里插入图片描述
主页显示
在这里插入图片描述
axios测试页
请求做过跨域处理,所以这个页面可以单独打开,不要求同源
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值