国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

GraphQL 核心概念

LancerComet / 3275人閱讀

摘要:系列文章核心概念本文淺嘗最近因?yàn)楣ぷ魃闲庐a(chǎn)品的需要,讓我有機(jī)會(huì)了解和嘗試。這篇文章主要分享的是的核心概念,主要分為和四部分。再次強(qiáng)調(diào),本文主要講的是的核心概念,中所定義的類,都是設(shè)計(jì)類,并不是具體實(shí)現(xiàn)代碼。

A query language created by Facebook for describing data requirements on complex application data models

系列文章:

GraphQL 核心概念(本文)

graphql-js 淺嘗

最近因?yàn)楣ぷ魃闲庐a(chǎn)品的需要,讓我有機(jī)會(huì)了解和嘗試 GraphQL。按照套路,在介紹一項(xiàng)新技術(shù)的時(shí)候總要回答 3 個(gè)問(wèn)題:What, Why & How。

What is GraphQL?

正如副標(biāo)題所說(shuō),GraphQL 是由 Facebook 創(chuàng)造的用于描述復(fù)雜數(shù)據(jù)模型的一種查詢語(yǔ)言。這里查詢語(yǔ)言所指的并不是常規(guī)意義上的類似 sql 語(yǔ)句的查詢語(yǔ)言,而是一種用于前后端數(shù)據(jù)查詢方式的規(guī)范。

Why using GraphQL?

當(dāng)今客戶端和服務(wù)端主要的交互方式有 2 種,分別是 REST 和 ad hoc 端點(diǎn)。GraphQL 官網(wǎng)指出了它們的不足之處主要在于:當(dāng)需求或數(shù)據(jù)發(fā)生變化時(shí),它們都需要建立新的接口來(lái)適應(yīng)變化,而不斷添加的接口,會(huì)造成服務(wù)器代碼的不斷增長(zhǎng),即使通過(guò)增加接口版本,也并不能夠完全限制服務(wù)器代碼的增長(zhǎng)。(更多不足,前往官網(wǎng)查看)

既然,GraphQL 指出了它們的缺點(diǎn),那么它自然解決了這些問(wèn)題。

如何解決的哪?那就得說(shuō)說(shuō) GraphQL 的 3 大特性。

首先,它是聲明式的。查詢的結(jié)果格式由請(qǐng)求方(即客戶端)決定而非響應(yīng)方(即服務(wù)器端)決定,也就是說(shuō),一個(gè) GraphQL 查詢結(jié)果的返回是同客戶端請(qǐng)求時(shí)的結(jié)構(gòu)一樣的,不多不少,不增不減。

其次,它是可組合的。一個(gè) GraphQL 的查詢結(jié)構(gòu)是一個(gè)有層次的字段集,它可以任意層次地進(jìn)行嵌套或組合,也就是說(shuō)它可以通過(guò)對(duì)字段進(jìn)行組合、嵌套來(lái)滿足需求。

第三,它是強(qiáng)類型的。強(qiáng)類型保證,只有當(dāng)一個(gè) GraphQL 查詢滿足所設(shè)定的查詢類型,那么查詢的結(jié)果才會(huì)被執(zhí)行。

回到之前的問(wèn)題,也就是說(shuō),當(dāng)需求或數(shù)據(jù)發(fā)生變化時(shí),客戶端可以根據(jù)需求來(lái)改變查詢的結(jié)構(gòu),只要查詢結(jié)構(gòu)滿足之前的定義,服務(wù)器端代碼甚至不需要做任何的修改;即使不滿足,也只需修改服務(wù)器端的查詢結(jié)構(gòu),而不必額外添加新的接口來(lái)滿足需求。

Core Concepts

可能你會(huì)問(wèn),按套路這節(jié)不該是 HOW to use GraphQL,怎么變成了 Core Concepts?

由于,GraphQL 是一種規(guī)范,于是,它的實(shí)現(xiàn)不限制某種特定語(yǔ)言,每種語(yǔ)言對(duì) GraphQL 都可以有自己的實(shí)現(xiàn),比如相對(duì) JavaScript 就有 graphql-js。既然,實(shí)現(xiàn)都不相同,那么,使用的方法也會(huì)不同,所以便不在這里細(xì)述了。

這篇文章主要分享的是 GraphQL 的核心概念,主要分為:Type System, Query Syntax, Validation Introspection 四部分。

Type System

類型系統(tǒng)是整個(gè) GraphQL 的核心,它用來(lái)定義每個(gè)查詢對(duì)象和返回對(duì)象的類型,將所有定義的對(duì)象組合起來(lái)就形成了一整個(gè) GraphQL Schema。

這個(gè)概念比較抽象,空說(shuō)很難理解,還是拿例子來(lái)邊看邊說(shuō)。個(gè)人博客相信大家都很熟悉,這里就嘗試用一個(gè)簡(jiǎn)單的博客系統(tǒng)的例子來(lái)說(shuō)明,這會(huì)比官網(wǎng)星戰(zhàn)的例子簡(jiǎn)單一點(diǎn)。

Let"s go!

既然是一個(gè)博客,那么,文章肯定少不了,我們首先來(lái)建立一個(gè)文章的類型。

type Post {
    id: String,
    name: String,
    createDate: String,
    title: String,
    subtitle: String,
    content: String
}

這樣,一個(gè)簡(jiǎn)單的文章類型就定義好了,它是一個(gè)自定義的類型,包含了一系列的字段,巧合的是這些字段的類型正好都是 String(字符串類型)。

String 沒(méi)有定義過(guò),為什么可以直接使用哪?因?yàn)椋?b>String 是 GraphQL 支持的 scalar type(標(biāo)量類型),默認(rèn)的標(biāo)量類型還包括 IntFloat, BooleanID

許多的博客網(wǎng)站都支持給每篇文章打標(biāo)簽,那么我們?cè)趤?lái)建立一個(gè)標(biāo)簽的類型。

type Tag {
    id: String,
    name: String,
    label: String,
    createDate: String
}

標(biāo)簽類型和文章類型怎么整合到一起哪?

GraphQL 不單單支持簡(jiǎn)單類型,還支持一些其他類型,如 Object, Enum, List, NotNull 這些常見(jiàn)的類型,還有 Interface, Union, InputObject 這幾個(gè)特殊類型。

PS:一直沒(méi)搞明白 InterfaceUnion 的區(qū)別在哪,它們分別適用于什么場(chǎng)景?谷歌了一下,還真有篇文章說(shuō)它們的區(qū)別,不過(guò)恕我愚鈍,還是沒(méi)能領(lǐng)悟,還望大神點(diǎn)撥...

再修改一下之前的文章類型,使一個(gè)文章可以包含多個(gè)標(biāo)簽。

type Post {
    id: String,
    name: String,
    createDate: String,
    title: String,
    subtitle: String,
    content: String,
    tags: [Tag]
}

通常在博客網(wǎng)站的標(biāo)簽列表中會(huì)顯示該標(biāo)簽下的一些文章,由于 GraphQL 是以產(chǎn)品為中心的,那么在標(biāo)簽類型下也可以有文章類型。于是,標(biāo)簽類就變成了

type Tag {
    id: String,
    name: String,
    label: String,
    createDate: String,
    posts: [Post]
}

可能你會(huì)疑惑,文章類型和標(biāo)簽類型這樣相互嵌套會(huì)不會(huì)造成死循環(huán)?我可以負(fù)責(zé)任的告訴你:不會(huì)。你可以盡情地嵌套、組合類型結(jié)構(gòu)來(lái)滿足你的需求。

最后,根據(jù)整個(gè)博客網(wǎng)站的需求,組合嵌套剛剛定義的文章類型和標(biāo)簽類型,建立一個(gè)根類型作為查詢的 schema。

type Blog {
    post: Post,        // 查詢一篇文章
    posts: [Post],    // 用于博客首頁(yè),查詢一組文章
    tag: Tag,        // 查詢一個(gè)標(biāo)簽
    tags: [Tag],    // 用于博客標(biāo)簽頁(yè),查詢所有標(biāo)簽
}

OK,我們的類型和 schema 都定義好了,就可以開(kāi)始查詢了。怎么查哪?那我們來(lái)看看 GraphQL 的查詢語(yǔ)法。

Query Syntax

GraphQL 的查詢語(yǔ)法同我們現(xiàn)在所使用的有一大不同是,傳輸?shù)臄?shù)據(jù)結(jié)構(gòu)并不是 JSON 對(duì)象,而是一個(gè)字符串,這個(gè)字符串描述了客戶端希望服務(wù)端返回?cái)?shù)據(jù)的具體結(jié)構(gòu)。

知道了概念,那么一個(gè) GraphQL 的查詢到底長(zhǎng)什么樣哪?繼續(xù)我們的例子,假設(shè),我們現(xiàn)在要查詢一篇文章,那么,GraphQL 的查詢語(yǔ)句就可以是這樣。

query FetchPostQuery {
    post {
        id,
        name,
        createDate,
        title,
        subtitle,
        content,
        tags {
            name,
            label
        }
    }
}

它相對(duì)應(yīng)的返回就會(huì)是類似這樣的一個(gè) JSON 數(shù)據(jù)。

{
    "data": {
        "post": {
            "id": "3",
            "name": "graphql-core-concepts",
            "createDate": "2016-08-01",
            "title": "GraphQL 核心概念",
            "subtitle": "A query language created by Facebook for decribing data requirements on complex application data models",
            "content": "省略...",
            "tags": [{
                "name": "graphql",
                "label": "GraphQL"
            }]
        }
    }
}

從中我們可以看到,數(shù)據(jù)返回了整個(gè)文章的屬性以及部分的標(biāo)簽屬性。其中,標(biāo)簽屬性并沒(méi)有返回全部的字段,而是只返回了 name 和 label 字段的屬性,做到了返回?cái)?shù)據(jù)的結(jié)構(gòu)完成同請(qǐng)求數(shù)據(jù)的結(jié)構(gòu)相同,沒(méi)有冗余的數(shù)據(jù)。

查詢添加參數(shù)的需求也非常基本,在 GraphQL 的查詢語(yǔ)法中也相當(dāng)簡(jiǎn)單,就拿剛剛的例子,要查詢特定的文章就可以把它改成這樣。

query FetchPostQuery {
    post(name: "graphql-core-concepts") {
        id,
        name,
        createDate,
        title,
        subtitle,
        content,
        tags {
            name,
            label
        }
    }
}

返回的結(jié)果會(huì)是和之前的一樣。查詢關(guān)鍵字只有在多個(gè)查詢時(shí)才必須,在單個(gè)查詢時(shí)可以省略。同時(shí),也可以對(duì)查詢的返回起別名,再來(lái)看看博客的首頁(yè)希望展示一個(gè)粗略的文章列表,那么這樣的一個(gè)查詢語(yǔ)句可以是

{
    postList: posts {
        id,
        name,
        createDate,
        title,
        subtitle,
        tags {
            name,
            label
        }
    }
}

這里,我們省略了查詢關(guān)鍵字,并將 posts 起了一個(gè)別名為 postList,返回的結(jié)果就會(huì)是

{
    "data": {
        "postList": [{
            "id": "3",
            "name": "graphql-core-concepts",
            "createDate": "2016-08-01",
            "title": "GraphQL 核心概念",
            "subtitle": "A query language created by Facebook for decribing data requirements on complex application data models",
            "tags": [{
                "name": "graphql",
                "label": "GraphQL"
            }]
        }, {
            "id": "2",
            "name": "redux-advanced",
            "createDate": "2016-07-23",
            "title": "Redux 進(jìn)階",
            "subtitle": "Advanced skill in Redux",
            "tags": [{
                "name": "javascript",
                "label": "JavaScript"
            }, {
                "name": "redux",
                "label": "Redux"
            }, {
                "name": "state-management",
                "label": "State management"
            }, {
                "name": "angular-1.x",
                "label": "Angular 1.x"
            }, {
                "name": "ui-router",
                "label": "ui-router"
            }, {
                "name": "redux-ui-router",
                "label": "redux-ui-router"
            }]
        }, {
            "id": "1",
            "name": "getting-started-with-redux",
            "createDate": "2016-07-06",
            "title": "Redux 入門",
            "subtitle": "A tiny predictable state management lib for JavaScript apps",
            "tags": [{
                "name": "javascript",
                "label": "JavaScript"
            }, {
                "name": "redux",
                "label": "Redux"
            }, {
                "name": "state-management",
                "label": "State management"
            }, {
                "name": "angular-1.x",
                "label": "Angular 1.x"
            }]
        }]
    }
}

同樣,查詢所有標(biāo)簽的語(yǔ)句就可以是這樣

{
    tags {
        id,
        name,
        label,
        posts {
            name,
            title
        }
    }
}

這樣,一個(gè) GraphQL 的接口,滿足了一個(gè)簡(jiǎn)單博客網(wǎng)站的所有需求,是不是很神奇?

Validation

由于 GraphQL 是一個(gè)強(qiáng)類型語(yǔ)言,所以它可以在執(zhí)行查詢之前檢查每個(gè)查詢語(yǔ)句是否滿足事先設(shè)定的 schema,符合則合法,如果查詢語(yǔ)句不合法則不進(jìn)行查詢。

以上所舉的都是合法的例子,官網(wǎng)上舉了一些例子,這里就不貼了,我們就總結(jié)看看要注意的有哪幾點(diǎn)。

fragment 不能引用自己從而形成一個(gè)循環(huán)

不能查詢類型中不存在的字段

查詢的字段如果不是 scalar type(標(biāo)量類型)或 enum type(枚舉類型),則需要明確該字段下所包含的字段

同上一條相對(duì),如果查詢字段是 scalar type(標(biāo)量類型),那么它就不能再有子字段

Introspection

Introspection 這個(gè)詞的意思是內(nèi)省,自我檢查(第一次發(fā)現(xiàn)英語(yǔ)有語(yǔ)義如此豐富的詞,又暴露詞匯量少了-_-||)。

不扯遠(yuǎn)了,在 GraphQL 中 Introspection 是一個(gè)非常有用的功能,它可以用來(lái)查詢當(dāng)前 GraphQL 的 schema,從而得知服務(wù)器端支持何種類型的查詢。

這是一個(gè)非常強(qiáng)大且有用的功能,可以想象一下,現(xiàn)在大型公司的開(kāi)發(fā)基本上都是前后端分離的,客戶端并不知道服務(wù)器端提供的 schema 結(jié)構(gòu),但通過(guò) Introspection,客戶端就能獲得當(dāng)前服務(wù)器端所提供的 schema,這無(wú)論對(duì)開(kāi)發(fā),還是調(diào)試錯(cuò)誤都很有幫助。

還是拿剛剛的博客系統(tǒng)來(lái)做例子,我們可以通過(guò)查詢 __schema 字段來(lái)獲得當(dāng)前所支持的查詢類型。

// query string
{
    __schema {
        types {
            name
        }
    }
}

// response data
{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "String"
        },
        {
          "name": "BlogType"
        },
        {
          "name": "PostType"
        },
        {
          "name": "ID"
        },
        {
          "name": "TagType"
        },
        {
          "name": "__Schema"
        },
        {
          "name": "__Type"
        },
        {
          "name": "__TypeKind"
        },
        {
          "name": "Boolean"
        },
        {
          "name": "__Field"
        },
        {
          "name": "__InputValue"
        },
        {
          "name": "__EnumValue"
        },
        {
          "name": "__Directive"
        },
        {
          "name": "__DirectiveLocation"
        }
      ]
    }
  }
}

從返回的數(shù)據(jù)中可以看到,我們自定義的 BlogType, PostType 和 TagType 類,剩下的都是 GraphQL 內(nèi)部類型,其中又分為兩類:一類是 ID, String 和 Bealoon 所表示的標(biāo)量類型,另一類以雙下劃線開(kāi)頭的是用于自我檢查的類型。

知道了自定義類,假設(shè),還想知道自定義類中包含哪些屬性以及屬性的類型,就可以這樣查詢

// query string
{
    __type(name: "PostType") {
        name
        fields {
            name,
            type {
                name,
                kind
            }
        }
    }
}

// response result
{
  "data": {
    "__type": {
      "name": "PostType",
      "fields": [
        {
          "name": "id",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "name",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "createDate",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "title",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "subtitle",
          "type": {
            "name": "String",
            "kind": "SCALAR"
          }
        },
        {
          "name": "content",
          "type": {
            "name": "String",
            "kind": "SCALAR"
          }
        },
        {
          "name": "tags",
          "type": {
            "name": null,
            "kind": "LIST"
          }
        }
      ]
    }
  }
}
最后

總結(jié)一下,GraphQL 是一種客戶端同服務(wù)端之間數(shù)據(jù)交互的概念,具有強(qiáng)大、靈活、易擴(kuò)展等的特點(diǎn)。既然,它是一種概念,那么,不同的語(yǔ)言就可以有各種不同的實(shí)現(xiàn)方式。

概念并不多,在于靈活運(yùn)用。

PS:再次強(qiáng)調(diào),本文主要講的是 GraphQL 的核心概念,Type System 中所定義的類,都是設(shè)計(jì)類,并不是具體實(shí)現(xiàn)代碼。實(shí)現(xiàn)請(qǐng)聽(tīng)下回分解。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90821.html

相關(guān)文章

  • graphql-js 淺嘗

    摘要:系列文章核心概念淺嘗本文常言道,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。遵循傳統(tǒng),第一個(gè)例子必須是。官方提供這個(gè)中間件來(lái)支持基于的查詢,所以,這里選用作為服務(wù)器。首先是,這里對(duì)做了一點(diǎn)小修改,給幾個(gè)字段添加了不能為空的設(shè)計(jì)。 系列文章: GraphQL 核心概念 graphql-js 淺嘗(本文) 常言道,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。 上一篇文章講了 GraphQL 的核心概念,所提到的一些例...

    gyl_coder 評(píng)論0 收藏0
  • GraphQL java工程化實(shí)踐

    摘要:我在工程實(shí)踐中直接使用類作為對(duì)應(yīng)實(shí)體類的。因此我的結(jié)論是,此庫(kù)并不適用于我的工程實(shí)踐。工程實(shí)踐中對(duì)其應(yīng)用方式的考慮在的官方教程中建議針對(duì)每請(qǐng)求創(chuàng)建新的實(shí)例,查詢請(qǐng)求結(jié)束則實(shí)例們的生命周期結(jié)束。 因?yàn)樽约簩戇^(guò)基于react的前端應(yīng)用,因此一看到GraphQL就被深深吸引,真是直擊痛點(diǎn)啊!服務(wù)端開(kāi)發(fā)一直是基于java, Spring的,因此開(kāi)始研究如何在現(xiàn)有工程框架下加入graphql的支...

    MSchumi 評(píng)論0 收藏0
  • GraphQL:一種更高效、強(qiáng)大和靈活的數(shù)據(jù)提供方式

    摘要:我們知道是一種從服務(wù)器公開(kāi)數(shù)據(jù)的流行方式。描述所有的可能類型系統(tǒng)基于類型和字段的方式進(jìn)行組織,而非入口端點(diǎn)。因此,需要對(duì)后端進(jìn)行調(diào)整,以滿足新的數(shù)據(jù)需求,這會(huì)降低生產(chǎn)力并顯著降低將用戶反饋集成到產(chǎn)品中的能力。 showImg(https://segmentfault.com/img/remote/1460000017875905?w=2234&h=974); 在前幾天的《StateOf...

    waruqi 評(píng)論0 收藏0
  • GraphQL:一種更高效、強(qiáng)大和靈活的數(shù)據(jù)提供方式

    摘要:我們知道是一種從服務(wù)器公開(kāi)數(shù)據(jù)的流行方式。描述所有的可能類型系統(tǒng)基于類型和字段的方式進(jìn)行組織,而非入口端點(diǎn)。因此,需要對(duì)后端進(jìn)行調(diào)整,以滿足新的數(shù)據(jù)需求,這會(huì)降低生產(chǎn)力并顯著降低將用戶反饋集成到產(chǎn)品中的能力。 showImg(https://segmentfault.com/img/remote/1460000017875905?w=2234&h=974); 在前幾天的《StateOf...

    zzbo 評(píng)論0 收藏0
  • GraphQL:一種更高效、強(qiáng)大和靈活的數(shù)據(jù)提供方式

    摘要:我們知道是一種從服務(wù)器公開(kāi)數(shù)據(jù)的流行方式。描述所有的可能類型系統(tǒng)基于類型和字段的方式進(jìn)行組織,而非入口端點(diǎn)。因此,需要對(duì)后端進(jìn)行調(diào)整,以滿足新的數(shù)據(jù)需求,這會(huì)降低生產(chǎn)力并顯著降低將用戶反饋集成到產(chǎn)品中的能力。 showImg(https://segmentfault.com/img/remote/1460000017875905?w=2234&h=974); 在前幾天的《StateOf...

    eccozhou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<