项目主页: https://github.com/TommyLemon/APIJSON
DB-Engines 发布了 2018 年 6 月份的数据库排名:
以及它们的历年发展走势:
很明显,Oracle, MySQL, Microsoft SQL Server 常年稳占前三名,
并且大幅超过其他数据库,只有这3个的 Score 在1000以上。
PostgreSQL 近年稳步上升,已跃居第4名。
以上前4大最流行的数据库都有一个共同点 —— 它们都是【关系型数据库】。
APIJSON 和 GraphQL 作为和 HTTP API 相关的通用开源项目,都必须支持 关系型数据库。
然后它们虽然都支持,但 APIJSON “完爆” GraphQL !
用 GraphQL 实现表关联查询是复杂繁琐的,而用 APIJSON 则非常简单方便!
关系型数据库之所以称之为“关系”型数据库,是因为它们能很好地支持【表关联查询】。
例如 查询当前用户的【全部信息】和TA的前5个朋友的【名字】
GraphQL 是这样查的:
{ user(id: 82001) { id sex name tag head contactIdList pictureList friends(first: 5) { name } } }
返回结果是
{ "data":{ "user":{ "id":82001, "sex":0, "name":"测试改名", "tag":"APIJSON User", "head":"https://static.oschina.net/uploads/user/19/39085_50.jpg", "contactIdList":[ 38710, 82002, 82006, 82030, 82025, 82003, 93793 ], "pictureList":[ "http://common.cnblogs.com/images/icon_weibo_24.png" ], "friends":[ { "name":"TommyLemon" }, { "name":"Happy~" }, { "name":"Wechat" }, { "name":"Meria" }, { "name":"Tommy" } ] } } }
GraphQL 后端怎么知道 user 的类型是 User,friends 的 类型是 User数组 呢?
因为后端提前用大量代码写死了数据结构和解析方式,也就是 Type 和 Schema :
//声明 GraphQLObjectType 类型,包括字段 fields 和解析函数 resolver var UserType = new GraphQLObjectType({ name: 'User', fields: () => ({ name: { type: GraphQLString }, friends: { args: { first: { type: GraphQLInt } }, type: new GraphQLList(UserType), //声明 friends 的类型是 User 数组 resolve: (user, { first }) => { //查 friends 的解析函数 var ids = user.contactIdList == null ? [] : user.contactIdList.join(); return ctx.db.findAll( 'SELECT name FROM User WHERE id IN(' + ids + ') LIMIT ' + first ).then(rows => rows.map(row => getUserFromRow(row))); } } }) });
//声明结构 Schema,包括 查询结构 Query export const UserSchema = new GraphQLSchema({ query: { user: { type: UserType //声明 me 的类型是 User fields: () => ({ id: { type: new GraphQLNonNull(GraphQLID) }, sex: { type: GraphQLInt }, name: { type: GraphQLString }, tag: { type: GraphQLString }, head: { type: GraphQLString }, contactIdList: { type: new GraphQLList(GraphQLID) }, pictureList: { type: new GraphQLList(GraphQLString) } }), args: { id: { type: new GraphQLNonNull(GraphQLID) } }, resolve: ({ id }) => { //查 User 的解析函数 return ctx.db.findOne( 'SELECT * FROM User WHERE id = ' + id ).then(row => getUserFromRow(row)); } } } });
以上代码是根据官方代码
https://github.com/graphql/gr...__tests__/starWarsSchema.js
https://github.com/facebook/d...
和 http://apijson.org 提供测试的数据库表 来实现的。
GraphQL 用 JavaScript 就这么复杂繁琐了,用 Java,C# 等静态类型语言会麻烦几倍!
APIJSON 是这样查的:
{ "User": { "id": 82001, //查询条件:id = 82001 "User[]": { //数组,提取里面每一项的 User "count": 5, //前 5 条:LIMIT 0, 5 "User": { "id{}@": "User/contactIdList", //在朋友id列表里:id IN contactIdList "@column": "name" //只查字段 name: SELECT name } } } }
或者把 User 数组放到外面减少嵌套层级(不知道GraphQL怎么实现,知道的留个评论谢谢)
{ "User": { "id": 82001 }, "User[]": { "count": 5, "User": { "id{}@": "User/contactIdList", "@column": "name" } } }
User 数组里每个对象里都只有 name 这一个字段,如果想去掉多余的一层包装,
APIJSON 可以【提取字段】(GraphQL 未提供)
{ "User": { "id": 82001 }, "User-name[]": { //从数组里面每个 User 里取出 name "count": 5, "User": { "id{}@": "User/contactIdList", "@column": "name" } } }
以上信息已经充分描述了 表、字段、查询条件、表关联方式 等信息。
APIJSON 后端不用写任何代码,
它会【完全自动】地 将以上请求 JSON 自动解析成 SQL 语句
SELECT * FROM User WHERE id = 82001
SELECT name FROM User WHERE id IN ${contactIdList} -- contactIdList 从上面的 User 取出
然后【自动执行】并返回对应结构的 JSON 结果!
点左边 [ '/" ] 按钮可以将数组符号 [] 转为单词 List 哦(用 JSONResponse.format 格式化)
注: 以上APIJSON请求都可以在 http://apijson.org 在线工具上测试
后期预告:
完爆Facebook/GraphQL,APIJSON全方位对比解析
—— 数据结构灵活性、接口安全性、接口工具、社区生态、静态类型/强类型 语言 …
总结
用 GraphQL 实现表关联查询是复杂繁琐的,后端要写大量代码,容易出错、扩展麻烦!
而用 APIJSON 则非常简单方便,后端不用写任何代码,完全自动解析,没有维护成本!
APIJSON,让后端接口和文档自动化,前端(客户端) 定制返回JSON的数据和结构!
创作不易,右上角点Star支持下吧,非常感谢^_^
https://github.com/TommyLemon/APIJSON (Java Server, Anroid, iOS, JavaScript)
https://github.com/liaozb/APIJSON.NET (C# .NET Core Server)