RestFullApi设计小技巧 --通用Api
在日常的开发中,我们会发现很多Api的功能几乎都是一样的,但是就因为他们的参数不同就要开发两套Api,今天就分享一个通用Api设计技巧,在中小型项目和个人项目里非常的实用。
传统restFullApi分析
仔细观察这四个Api,它们都做了同一件事情,那就是把前端传来的数据存库,然后在把结果返回给前端,只是api的url,以及数据库的地址不一样而已。
试想一下,这两个模块,要实现增删改查,至少需要写8-10个Api,然后基本上都是重复工作。一个Api文件里写的满满当当,但是都是重复性劳动。
//api.js
//添加一篇文章
app.post("/api/article", async (req, res) => {
const db = require('./articleModel');
let article = await db.create(req.body);
res.send(article)
}
//查找一篇博客
app.get("/api/article/:id", async (req, res) => {
const db = require('./articleModel');
let article = await db.findById(req.params.id);
res.send(article)
}
//添加一个标签
app.post("/api/tag", async (req, res) => {
const db = require('./tagModel');
let tag= await db.create(req.body);
res.send(tag);
}
//查找一个标签
app.get("/api/tag/:id", async (req, res) => {
const db = require('./tagModel');
let tag= await req.Model.findById(req.params.id);
res.send(tag)
}Api改造
通过上面的Api分析,我们了解到,api重复只是因为他们的url和db路径不同,那么我们可以不可以把Url也作为路由的参数,然后根据路由参数去固定的路径找对应的dbModel呢?
//提交一份数据
app.post("/api/rest/:resource", async (req, res) => {
const db = require(`./${req.params.resource}`);
let data= await db.create(req.body);
res.send(data);
}
//查找一份数据
app.get("/api/rest/:resource/:id", async (req, res) => {
const db = require(`./${req.params.resource}`);
let data = await req.Model.findById(req.params.id);
res.send(data);
}更进一步
1.安装插件inflection
我们需要借助一个插件inflection,这个插件主要用处是进行文字处理,在做自动化的时候非常好用。比如他的classify可以将单词转为类名。
代码示例:
var inflection = require( 'inflection' );
inflection.classify( 'message_bus_properties' ); //==='MessageBusProperty'
2.将数据库模型挂载到req