完爆Facebook/GraphQL,APIJSON全方位對比解析(三)-表關聯查詢

相關閱讀:javascript

完爆Facebook/GraphQL,APIJSON全方位對比解析(一)-基礎功能前端

完爆Facebook/GraphQL,APIJSON全方位對比解析(二)-權限控制java

自APIJSON發佈以來,不斷有網友拿來和Facebook的GraphQL對比,git

甚至有很多人聲稱「完爆」APIJSON。github

然而事實正好相反,本系列博客將以大量真實依據來證實,sql

APIJSON「完爆」GraphQL!數據庫

APIJSON的口號是:json

後端接口和文檔自動化,前端(客戶端) 定製返回JSON的數據和結構!後端

APIJSON的簡介:api

APIJSON是一種爲API而生的JSON網絡傳輸協議。
爲 簡單的增刪改查、複雜的查詢、簡單的事務操做 提供了徹底自動化的API。
能大幅下降開發和溝通成本,簡化開發流程,縮短開發週期。
適合中小型先後端分離的項目,尤爲是互聯網創業項目和企業自用項目。

經過自動化API,前端能夠定製任何數據、任何結構!
大部分HTTP請求後端不再用寫接口了,更不用寫文檔了!
前端不再用和後端溝通接口或文檔問題了!不再會被文檔各類錯誤坑了!
後端不再用爲了兼容舊接口寫新版接口和文檔了!不再會被前端隨時隨地沒完沒了地煩了!

特色功能

在線解析

  • 自動生成文檔,清晰可讀永遠最新
  • 自動生成請求代碼,支持Android和iOS
  • 自動生成JavaBean文件,一鍵下載
  • 自動管理與測試接口用例,一鍵共享
  • 自動校驗與格式化JSON,支持高亮和收展

對於前端

  • 不用再向後端催接口、求文檔
  • 數據和結構徹底定製,要啥有啥
  • 看請求知結果,所求即所得
  • 可一次獲取任何數據、任何結構
  • 能去除重複數據,節省流量提升速度

對於後端

  • 提供通用接口,大部分API不用再寫
  • 自動生成文檔,不用再編寫和維護
  • 自動校驗權限、自動管理版本
  • 開放API無需劃分版本,始終保持兼容
  • 支持增刪改查、模糊搜索、正則匹配、遠程函數等

視頻演示:http://i.youku.com/apijson

[如下Gif圖看起來比較卡,實際在手機上App運行很流暢]

項目主頁: https://github.com/TommyLemon/APIJSON

完爆Facebook/GraphQL,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)

相關文章
相關標籤/搜索