GraphQL入門——關於數據的解析粒度

GraphQL解析粒度

引言

關於GraphQL的基礎概念,能夠參看前一篇文章《更輕鬆的使用GraphQL》javascript

困惑

初次看到GraphQL,很容易被它強大的介紹所吸引,但想更進一步嘗試時,卻會發現它的」hello world「不是很友好,容易讓人打退堂鼓。java

咱們首先看一下官方(grpahql-js)的例子:git

var schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      hello: {
        type: GraphQLString,
        resolve() {
          return 'world';
        }
      }
    }
  })
});

其中,resolve函數定義部分,換成更直觀一些的寫法(僞代碼)就是:github

{
    // 每一個field獨立的resolve函數
    hello: function resolve () {
        return 'world';
    }
}

這就讓人很懼怕了,一個數據結構中的每一個成員都要定義一個resolve函數的話,工做量和開發複雜度就使人難以接受了,因此不少人看了官方README就被嚇退了。數據結構

但實際上,GraphQL是能夠整個對象使用一個resolve函數來獲取全部field的數據,看僞代碼大概就是:函數

{   // 整個對象使用一個resolve函數
    hello,
    xxx,
    foo,
    ...
} : function resolve () {
    return {
        hello : "world",
        foo : "bar",
        ...
    };
}

實戰

咱們仍是以論壇帖子爲例:post

1. schema定義

用戶定義:fetch

# user schema
type User {
    uid : ID!
    name : String!
    avatar : String!
}

帖子定義:ui

# post schema
type Post {
    pid : ID!
    title : String!
    content : String!
    author : User!
}

2. 提供的查詢方法定義

查詢定義:.net

type Query {
    post(id: ID): Post
}

3. 對應的resolve函數編寫

'use strict'

const fakeDB = require('../../fakeDB');

function fetchPostById (root, {id}, ctx) {
    // post的查詢,第二個參數是查詢語句中傳入的
    let pid = parseInt(id);
    return fakeDB.getPostById(pid);
}

// 對post下的author字段進行查詢解決的函數
function fetchUserByAuthorId (root, args, ctx) {
    // 執行完post的數據查詢後,遇到須要author字段的狀況,會再來調用本函數,root參數就是前一步查詢完的post數據
    let uid = root.authorId;
    return fakeDB.getUserById(uid);
}

const postReolvers = {
    Query : {
        post : fetchPostById,
    },

    Post : {
        // 針對嵌套的數據結構須要的解決函數
        author : fetchUserByAuthorId,
    },
};
module.exports = postReolvers;

4. 查詢的結果

經過上面的fetchPostById函數,就能查詢指定id的帖子詳情(整個Post數據結構)了,而無需對Post的每一個field分別定義resolve函數:

查詢返回結果以下:

{
  "data": {
    "post": {
      "pid": "1",
      "title": "foo",
      "content": "xxx",
      "author": {
        "uid": "1",
        "name": "Tom",
        "avatar": "https://pre00.deviantart.net/2930/th/pre/i/2014/182/a/2/tom_cat_by_1997ael-d7ougoa.png"
      }
    }
  }
}

結語

但願本文能對你們初步瞭解GraphQL有所幫助,不要被官方「hello world」給嚇退了,而可以去進一步嘗試一下GraphQL。

歡迎使用更簡單的GraphQL封裝庫:easy-graphql

相關文章
相關標籤/搜索