相关阅读:
完爆Facebook/GraphQL,APIJSON全方位对比解析(一)-基础功能
自APIJSON发布以来,不断有网友拿来和Facebook开发的GraphQL对比,甚至不少人声称“完爆”APIJSON。
然而事实正好相反,本系列博客将以大量真实依据来证明,APIJSON“完爆”GraphQL!
APIJSON的口号是:
后端接口和文档自动化,前端(客户端) 定制返回JSON的数据和结构!
APIJSON的简介:
APIJSON是一种为API而生的JSON网络传输协议。
为 简单的增删改查、复杂的查询、简单的事务操作 提供了完全自动化的API。
能大幅降低开发和沟通成本,简化开发流程,缩短开发周期。
适合中小型前后端分离的项目,尤其是互联网创业项目和企业自用项目。
通过自动化API,前端可以定制任何数据、任何结构!
大部分HTTP请求后端再也不用写接口了,更不用写文档了!
前端再也不用和后端沟通接口或文档问题了!再也不会被文档各种错误坑了!
后端再也不用为了兼容旧接口写新版接口和文档了!再也不会被前端随时随地没完没了地烦了!
特点功能
在线解析
- 自动生成文档,清晰可读永远最新
- 自动生成请求代码,支持Android和iOS
- 自动生成所有JavaBean,一键下载
- 自动管理与测试接口用例,一键共享
- 自动校验与格式化JSON,支持高亮和收展
对于前端
- 不用再向后端催接口、求文档
- 数据和结构完全定制,要啥有啥
- 看请求知结果,所求即所得
- 可一次获取任何数据、任何结构
- 能去除重复数据,节省流量提高速度
对于后端
- 提供通用接口,大部分API不用再写
- 自动生成文档,不用再编写和维护
- 自动校验权限、自动管理版本
- 开放API无需划分版本,始终保持兼容
- 支持增删改查、模糊搜索、正则匹配、远程函数等
视频演示:http://i.youku.com/apijson
自动化权限控制(APIJSON特有):
GraphQL【没有】提供权限控制的功能,甚至在官方文档和源码里连如何实现的教程也几乎没有,
而仅仅提及了如何在你的【业务代码】里去【手动】实现一个【所属人】角色的权限控制。
高亮的这行代码
if (context.user && (context.user.id === post.authorId))
复制代码
就是在后端手动写的postType中,手动加的resolve函数里,加上这么一个userId关系判断。
也就只能实现当查询postType对应的表时,只有post里的authorId和来访user的id相等时,才返回查到的结果。
下文中善意地提示了你,不要写死在某个Type的resolver函数中,
而是应该封装到一个postReponsitory,里面放一个getBody的函数,内部再实现这个判断并return。
这样不仅逻辑清晰,还能在别的Type中用到postType时(例如userType嵌套postType)可以复用。(PS: 这个文档中没说,我帮它说了)
但即便你花了时间去新写一个类、再新写一个函数,做了这个封装,那也只是postType能复用而已,
其它的humanType,droidType,queryType等一大堆Type不都还是得一个个写?
https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsSchema.js
而且当今的互联网应用中,不管是网站,还是移动端App,稍微复杂一点的都不只是【所属人】这么一个角色,
其中大部分,尤其是社交应用,都包含 【联系人】、【朋友圈】这两个角色。
当然,所有具有账户登录的应用,都可以分【已登录】、【未登录】这两种角色。
既然GraphQL不提供权限控制功能,那就只能自己根据每种角色一个个写了。
按照以上唯一一个官方示例,我们对应所有角色的判断应该是:
未登录:
if (context.user == null || context.user.id == null || context.user.id <= 0) {
return post.body;
}
return null;
复制代码
已登录:
if (context.user && context.user.id && context.user.id > 0) {
return post.body;
}
return null;
复制代码
朋友圈:
var userId = context.user == null ? null : context.user.id;
var contactIdList = context.user == null ? null : context.user.contactIdList; //联系人id列表
if ((userId && userId === post.authorId) || (contactIdList && contactIdList.indexOf(post.authorId) >= 0)) {
return post.body;
}
return null;
复制代码
联系人:
var contactIdList = context.user == null ? null : context.user.contactIdList; //联系人id列表
if (contactIdList && contactIdList.indexOf(post.authorId) >= 0) {
return post.body;
}
return null;
复制代码
所属人:
if (context.user && (context.user.id === post.authorId)) {
return post.body;
}
return null;
复制代码
仅仅用GraphQL实现查询postType这一个Type对应的角色权限控制,居然就要写这么多判断代码!
假设我们数据库有20张表(实际很轻量级的应用才只有这么少的表),对应写了20个Type,那就是 20*5 = 100 个判断!!!
仅仅是判断角色权限的代码就至少有 20*(4 + 4 + 6 + 5 + 4) = 460 行!!!
而APJSON提供了自动化的权限控制,可以细分到 每张表、每行记录、每种角色、每种操作 的控制粒度!
而且每张表只需要写3行代码就能配置各种角色的增删改查的权限!
我们用APIJSON来操作一张表,例如用户表User,代码写3行就够了:
//注册表并添加权限,用默认配置
@MethodAccess
public class User {
//内容一般仅供表字段说明及Android App开发使用,服务端不用的可不写。
}
//DemoVerifier内添加权限
ACCESS_MAP.put(User.class.getSimpleName(), getAccessMap(User.class.getAnnotation(MethodAccess.class)));
复制代码
或者可以再定制下POST请求的角色权限:
@MethodAccess(
POST = {UNKNOWN, ADMIN} //只允许未登录角色和管理员角色新增User,默认配置是 {LOGIN, ADMIN}
)
public class User {}
复制代码
然后运行下Server工程就可以请求了:
URL:http://apijson.cn:8080/get
请求:
{
"User": {
"id": 82001
}
}
复制代码
返回:
{
"User": {
"id": 82001,
"sex": 0,
"name": "Test",
"tag": "APIJSON User",
"head": "http://static.oschina.net/uploads/user/19/39085_50.jpg",
"contactIdList": [
82004,
82021,
70793
],
"pictureList": [
"http://common.cnblogs.com/images/icon_weibo_24.png"
],
"date": "2017-02-01 19:21:50.0"
},
"code": 200,
"msg": "success"
}
复制代码
复制代码
我们再试试APIJSON的自动化权限控制到底 能不能达到期望、会不会被绕过 吧。
查询用户开放信息User:
/get/{"User":{"id":38710}}
请求成功:
{
"User": {
"id": 38710,
"sex": 0,
"name": "TommyLemon",
"tag": "Android&Java",
"head": "http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
"contactIdList": [
82003,
82005,
90814,
82004,
82009,
82002,
82044,
93793,
70793
],
"pictureList": [
"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
"http://common.cnblogs.com/images/icon_weibo_24.png"
],
"date": "2017-02-01 19:21:50.0"
},
"code": 200,
"msg": "success"
}
复制代码
查询用户隐私信息Privacy:
/get/{"Privacy":{"id":38710}}
请求失败,无GET权限:
{
"Privacy": {
"id": 38710
},
"code": 401,
"msg": "Privacy 不允许 UNKNOWN 用户的 GET 请求!"
}
复制代码
看下源码:
@MethodAccess(
GET = {},
GETS = {OWNER, ADMIN}
)
public class Privacy {}
复制代码
很明显,get是不允许的,可以用gets,但也必须是OWNER, ADMIN这2种角色中的一个。
URL: http://apijson.cn:8080/gets/
请求:
{
"Privacy": {
"id": 38710
},
"tag": "Privacy"
}
复制代码
仍然失败,因为没登录,未登录是UNKNOWN用户,这里自动补全为OWNER:
{
"Privacy": {
"id": 38710
},
"tag": "Privacy",
"code": 407,
"msg": "未登录,请登录后再操作!"
}
复制代码
那我们能不能伪造一下角色骗过APIJSON呢?试试看:
{
"Privacy": {
"id": 38710,
"@role": "circle"
},
"tag": "Privacy"
}
复制代码
还是一样的报错:未登录。
{
"Privacy": {
"id": 38710,
"@role": "circle"
},
"tag": "Privacy",
"code": 407,
"msg": "未登录,请登录后再操作!"
}
复制代码
好吧,我登录后再试,新的报错:
{
"Privacy": {
"id": 38710,
"@role": "circle"
},
"code": 401,
"msg": "Privacy 不允许 CIRCLE 用户的 GETS 请求!"
}
复制代码
为什么呢?角色不符合OWNER, ADMIN这2种角色中的一个。
那换成OWNER角色呢?
{
"Privacy": {
"id": 38710,
"@role": "owner"
},
"tag": "Privacy"
}
复制代码
继续报错:
{
"Privacy": {
"id": 38710,
"@role": "owner"
},
"code": 401,
"msg": "id = 38710 的 Privacy 不允许 OWNER 用户的 GETS 请求!"
}
复制代码
换成后端没有的角色呢?
{
"Privacy": {
"id": 38710,
"@role": "test"
},
"tag": "Privacy"
}
复制代码
报错,角色不存在:
{
"Privacy": {
"id": 38710 ,
"@role": "test"
},
"code": 406 ,
"msg": "角色 test 不存在!只能是[UNKNOWN,LOGIN,CONTACT,CIRCLE,OWNER,ADMIN]中的一种!"
}
复制代码
再试试 "@role": "admin" :
{
"Privacy": {
"id": 38710,
"@role": "admin"
},
"tag": "Privacy"
}
复制代码
仍然报错:
{
"Privacy": {
"id": 38710,
"@role": "admin"
},
"code": 406,
"msg": "角色设置错误!不允许在写操作Request中传 Privacy:{ @role:admin } !"
}
复制代码
管理员角色是只能在服务器内部设置的,不允许传哦。
所以,按照Privacy的权限配置,前端只有用OWNER角色去查当前已登录账户(id=82001)的Privacy:
{
"Privacy": {
"id": 82001,
"@role": "owner" //Request表中配置了自动补全,可不写
},
"tag": "Privacy"
}
复制代码
才会返回正确的结果:
{
"Privacy": {
"id": 82001,
"certified": 1,
"phone": 13000082001,
"balance": 8781.46
},
"code": 200,
"msg": "success"
}
复制代码
注: 以上APIJSON请求都可以在 http://apijson.cn 在线工具上测试
总结
GraphQL没有提供权限控制的功能,需要后端针对每张表对应的Type去对应各种角色一个个手写大量判断代码!
而APJSON提供了自动化的权限控制,可以细分到 每张表、每行记录、每种角色、每种操作 的控制粒度!
而且每张表只需要写3行代码就能配置各种角色的增删改查的权限!以上测试用例也说明了它不但配置简单还很可靠!
APIJSON,让后端接口和文档自动化,前端(客户端) 定制返回JSON的数据和结构!
创作不易,右上角点Star支持下吧,非常感谢^_^
github.com/TommyLemon/…