@mora/foe-api v0.6.0
foe-api
给前端程序员使用的后端接口统一管理工具(支持 TypeScript)
背景
在开发一个项目时,后端接口比较分散,没有一个统一的管理工具,如果不看接口使用说明,也无法知道接口需要什么参数,返回什么数据。
所以设计 foe-api 的初衷主要是为了解决上面问题。同时在设计 foe-api 的时候,由于采用了类 koa 的插件机制,可以在一个插件中,对请求之前的数据进行处理,也可以对讲求之后返回的数据进行处理。所以利用这个插件机制,可以使 foe-api 更强大,如:
- 可以实现接口数据缓存
- 可以对返回的数据的键名统一格式化(比如后端返回的键名都是下划线形式的,可以使用插件将其转化成驼峰形式)
- 可以自定义你自己的 fetch 请求(比如可以使用原生的 window.fetch,也可以使用 jquery 的 ajax 等等,只需要将返回的数据放到 Context.body 中即可)
- 可以轻松实现接口 mock
使用示例
import { Application } from 'foe-api'
//========= 初始化 ==========//
let app = new Application({
/* 配置一:初始化配置 */
})
//========= 使用插件 ==========//
app.use(async (ctx, next) => { // 类似于 koa 的插件方式,系统默认提供 fetch、mock 等插件
if (ctx.name === 'getUser') {
ctx.body = {id: 1, name: 'Alex', age: 20} // 调用接口的时候,会将 body 中的内容返回给调用者
}
await next()
})
//========= 定义接口 ==========//
/** 调用接口时需要的参数的定义 */
interface IgetUserParam {
id: number
}
/** 接口返回的数据定义 */
interface IgetUserReturn {
id: number
name: string
age: number
}
let getUser = app.api<IgetUserParam, IgetUserReturn>('getUser', {
/* 配置二:定义时的配置 */
path: '/api/user/:id',
method: 'GET'
})
//========= 调用接口 ==========//
getUser({id: 0}, { /* 配置三:调用时的配置 */ })
.then(user => {
console.log(user) // user 将会是 {id: 1, name: 'Alex', age: 20}
})
关于调用接口时传的参数
以上面的 getUser
接口为例,第一个参数 {id: 0}
会安一定的规则分配给配置中的 path
、query
、body
三个字段,分配规则是:
- 优先分配给
path
中带:
前缀的参数,如上面 path 配置/api/user/:id
中的:id
- 如果有配置
query
,就会将对应的参数分配给它(上面没有配置 query,所以没有;配置方法见下面的『配置』模块) - 如果有配置
body
,则只会分配配置好的参数给它 - 如果没有配置
body
,并且接口支持配置body
(GET 请求不支持配置body
),则会将除去path
和query
中的参数,剩下的所有参数分配给body
提交给后台
配置
在使用过程中,可以在三个不同的地方对接口进行配置:
- 初始化 Application 的时候
- 使用 Application.api 定义接口的时候
- 调用接口的时候
三个地方的配置项都是一样的,系统会在调用的时候将三个地方的配置进行合并,传给 Context.config 变量
配置项
basePath
基本的 path,所有的 path 都会加上此 basePath,默认为空字符串
如,basePath = 'http://backend.com/v1'; path = '/user/:id';
则,最终的 path 为 'http://backend.com/v1/user/:id'
basePath 中也可以带参数,最终只是会将 basePath 和 path 合并生成新的 path
path
带参数的 url 路径,参数前面需要加 :
以区别,如:
获取用户信息接口(需要传 uid 给后端)=> /api/user/:uid
method
和在 http 中配置 method 一样,但这里配置的优先级比 http.method 中配置高,所以优先会使用此处配置的值
http
window.fetch 相关选项,可以在这里指定 header 等信息
query
指定需要提供的 query 参数的一些规则
如果有 query,一定需要配置 query,否则不会自动将参数添加到 path 中
可以配置成对象形式,如
{ uid: {required: true, type: 'number', backend: 'userid'}, version: {required: false, type: 'number', defaultValue: 3} }
上面的配置表示
uid
参数必填,并且组装成 url 时会变成userid
传给后端;而version
参数可以不填,默认值为3
。 如果path="/api/user"
,同时使用{uid: 10}
去调用此 api 的话,组装后的url
为"/api/user?userid=10&version=3"
由于对象形式的配置太过繁杂,所以支持一种简化的字符串方式的配置,如上面的配置可以配置成:
"uid:number>userid=&version:number=3"
规则是:
- 第一个参数是键名,如
uid
,version
:
后面的名称表示参数类型,如:number
>
后面的名称表示传给后端的名称,即backend
配置,如>userid
- 如果没有
=
,表示此值是选填的 - 如果有
=
,并且=
后面没有值,表示此值是必填的 - 如果有
=
,并且=
后面有值的话,表示此值是选填的,并且=
后面的值即为此参数的默认值
- 第一个参数是键名,如
示例:
- 'uid' 转化成 uid: { }
- 'uid=' 转化成 uid: { required: true }
- 'uid:number=3' 转化成 uid: { type: 'number', defaultValue: 3 }
'uid>userid=4' 转化成 uid: { backend: 'userid', required: true, defaultValue: '4' }
建议都加上 type,方便在前端做个简单的验证,提前发现错误
body
指定需要提供的 body 参数的一些规则
当没有指定 body 时,会使用用户提供的所有参数,去除 path 中的和 query 中的参数,将剩下的所有参数当作 body 发送
和 query 配置方法类似,请参考 query
如果要发送的 body 不是对象时,可以使用 __rawBody
字段
debug
是否启用 debug
mock
mock 相关选项
设置成 false
表示禁用 mock, true
表示启用 mock
另外,也可以设置成对象 {enable: true, delay: 300}
, 表示此 mock 数据延迟 300 毫秒再返回
6 years ago