【CuteJavaScript】GraphQL真香入門教程

封面

看完復聯四,我整理了這份 GraphQL 入門教程,哈哈真香。。。html

歡迎關注個人 我的主頁 && 我的博客 && 我的知識庫 && 微信公衆號「前端自習課」

首先有請阿爸鎮貼!哈哈哈,須要高清原圖的小夥伴能夠 點我下載 阿爸無敵前端

iron_man

下面開始本文內容:node

1、GraphQL介紹

GraphQL 是 Facebook 開發的一種 API 的查詢語言,與 2015 年公開發布,是 REST API 的替代品。 git

GraphQL 既是一種用於 API 的查詢語言也是一個知足你數據查詢的運行時GraphQL 對你的 API 中的數據提供了一套易於理解的完整描述,使得客戶端可以準確地得到它須要的數據,並且沒有任何冗餘,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。 github

官網: http://graphql.org/
中文網: http://graphql.cn/mongodb

1. 特色

  • 請求你所要的數據,很少很多;

如:hero 中有 name, age, sex 等,能夠只取得須要的字段。chrome

  • 獲取多個資源,只用一個請求;

典型的 REST API 請求多個資源時得載入多個 URL,而 GraphQL 能夠經過一次請求就獲取你應用所需的全部數據。這樣也能保證在較慢的移動網絡鏈接下,使用 GraphQL 的應用也能表現得足夠迅速。數據庫

  • 描述全部可能類型的系統。便於維護,根據需求平滑演進,添加或隱藏字段;

GraphQL 使用類型來保證應用只請求可能的數據,還提供了清晰的輔助性錯誤信息。應用可使用類型,而避免編寫手動解析代碼。express

2. 簡單案例

這裏先看下簡單案例,體驗下 GraphQL 的神奇之處(後面詳細介紹)。
咱們這樣定義查詢語句:npm

query {
    hero
}

而後獲得的就是咱們所要查詢的 hero 字段:

{
    "data": {
        "hero": "I'm iron man"
    }
}

這樣用起來,是否是更舒服呢?

2、GraphQL與restful對比

1. restful介紹

全稱:Representational State Transfer 表屬性狀態轉移。
本質上就是定義 uri ,經過 API 接口來取得資源。通用系統架構,不受語言限制。

例子: 餓了嗎接口。
如:接口 restapi/shopping/v3/restaurants?latitude=13 就是個典型的 restful 接口,定義資源 + 查詢條件。

2. 與 GraphQL 比較

  • restful 一個接口只能返回一個資源,GraphQL 一次能夠獲取多個資源。
  • restful 用不一樣 url 來區分資源,GraphQL 用類型區分資源。

3、使用express構建基本helloworld

1. 簡單案例

首先建立一個文件夾 demo ,並初始化一個 package.json,安裝 express / graphql / express-graphql 依賴包:

npm init -y
npm install express graphql express-graphql -S

新建一個 hello.js,引入文件:

const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')

建立一個 schema 來定義查詢語句和類型,buildSchema() 方法須要傳入的參數是字符串類型,以下面的 hero 查詢字段,後面的 String 類型表示字段返回的數據類型:

const schema = buildSchema(`
    type Query {
        hero: String
    }
`)

建立一個 root 處理器,處理對應的查詢,這裏的 hello 處理器對應的是 schema 中的 hero 字段查詢的處理,這裏直接返回 I'm iron man 的結果:

const root = {
    hero: () => {
        return "I'm iron man"
    }
}

固然,處理器中也能夠是其餘複雜操做,後面會介紹。

而後實例化 express ,而且將路由轉發給 graphqlHTTP 處理:

const app = express()
app.use('/graphql', graphqlHTTP({
    schema,
    rootValue: root,
    graphiql: true
}))
app.listen(3000)

graphqlHTTP 中的三個參數介紹:

  • schema:定義的查詢語句和類型
  • rootValue:處理對應查詢的處理器
  • graphiql:是否開啓調試窗口,開發階段開啓,生產階段關閉

接下來運行項目,在命令行中執行 node hello.js,這裏能夠在 graphiql 上作調試,打開地址 localhost:3000/graphiql 就能夠愉快的查詢了。

1

另外咱們能夠在 graphiql 界面右側打開 Docs 查看咱們定義的全部字段和描述信息。

2

3

最終代碼:

const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')

// 構建schema,這裏定義查詢的語句和類型
const schema = buildSchema(`
    type Query {
        hero: String
    }
`)

// 定義查詢所對應的 resolver,也就是查詢對應的處理器
const root = {
    hero: () => {
        return "I'm iron man"
    }
}

const app = express()

// 將路由轉發給 graphqlHTTP 處理
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true
}))

app.listen(3000)

2. 自定義類型查詢

咱們前面的查詢中,已經將 hero 字段定義爲 String 類型,可是經常開發中,咱們又會碰到字段是多個類型,即字段也能指代對象類型(Object),好比一個 user 字段會有 nameage 等字段,而 name 返回字符串類型,age 返回數值類型。

這時候,咱們能夠對這個對象的字段進行次級選擇(sub-selection)。GraphQL 查詢可以遍歷相關對象及其字段,使得客戶端能夠一次請求查詢大量相關數據,而不像傳統 REST 架構中那樣須要屢次往返查詢。

咱們能夠新建一個查詢類型來定義 user 字段返回的類型:

const schema = buildSchema(`
    type User {
        # 查詢能夠有備註!
        name: String
        age: Int
    }
    type Query {
        hero: String
        user: User
    }
`)

在處理器中咱們也要加上:

const root = {
    hero: () => {
        return "I'm iron man"
    },
    user: () => {
        return {
            name: 'leo',
            age: 18
        }
    }
}

這邊 Int/String 參數類型的問題,下一章介紹

4、參數類型和參數傳遞

1. 基本參數類型

String, Int, Float, BooleanID,這些基本參數類型能夠在 schema 聲明中直接使用。

  • Int:有符號 32 位整數。
  • Float:有符號雙精度浮點值。
  • StringUTF‐8 字符序列。
  • Booleantrue 或者 false
  • IDID 標量類型表示一個惟一標識符,一般用以從新獲取對象或者做爲緩存中的鍵。ID 類型使用和 String 同樣的方式序列化;然而將其定義爲 ID 意味着並不須要人類可讀型

另外,咱們可使用 [類型] 來表示一類數組,如:

  • [Int] 表示整型數組;
  • [String] 表示字符串型數組;

2. 參數傳遞

使用方式和 JS 參數傳遞同樣,小括號內定義形參,可是參數須要定義類型

使用 ! 表明參數不能爲空。

下面案例:參數 teamNameString 類型,必須傳遞,而 number 參數也是 Int 類型,可是是非必須傳遞,最後輸出的結果也是 String 類型。

type Query {
    getHero(teamName: String!, number: Int): [String]
}

下面一個案例:

//...省略其餘
const schema = buildSchema(`
    type Query {
        getHero(teamName: String!): [String]
    }
`)

const root = {
    getHero: ({teamName}) => {
        // 這裏的操做 實際開發中經常用在請求數據庫
        const hero = {
            '三國': ['張飛', '劉備', '關羽'],
            '復仇者聯盟': ['鋼鐵俠', '美國隊長', '綠巨人']
        }
        return hero[teamName]
    }
}
//...省略其餘

這時候咱們在 GraphiQL 上輸入查詢,就會獲得 復仇者聯盟 的英雄數據了。

// 查詢
query {
    getHero(teamName:"復仇者聯盟")
}

// 結果
{
    "data": {
        "getHero": [
            "鋼鐵俠",
            "美國隊長",
            "綠巨人"
        ]
    }
}

3. 自定義返回類型

在實際開發中,咱們返回的數據類型多是一個對象,對象中可能既有 Int 類型的屬性,也有 String 類型的值,等等,這裏咱們可使用 自定義返回類型 來處理:

//...省略其餘
const schema = buildSchema(`
    type Hero {
        name: String
        age: Int
        doSomething(thing: String): String
    }
    type Query {
        getSuperHero(heroName: String!): Hero
    }
`)
const root = {
    getSuperHero: ({heroName}) => {
        // 這裏的操做 實際開發中經常用在請求數據庫
        const name = heroName
        const age = 18
        const doSomething = ({thing}) => {
            return `I'm ${name}, I'm ${thing} now`
        }
        return { name, age, doSomething }
    }
}
//...省略其餘

這裏指定了 getSuperHero 字段的返回類型是 Hero 類型,隨後在上面定義了 Hero

其中 Hero 類型中的 doSomething也是能夠傳遞指定類型參數,而且指定返回類型。

下面看下輸出狀況:

// 查詢
query {
    getSuperHero(heroName:"IronMan") {
        name
        age
        doSomething
    }
}

// 結果
{
    "data": {
        "getSuperHero": {
            "name": "IronMan",
            "age": 46,
            "doSomething": "I'm IronMan, I'm undefined now"
        }
    }
}

這裏也能夠給 doSomething 傳遞參數,就會獲取到不一樣結果:

// 查詢
query {
    getSuperHero(heroName:"IronMan") {
        name
        age
        doSomething(thing:"watching TV")
    }
}

// 結果
{
    "data": {
        "getSuperHero": {
            "name": "IronMan",
            "age": 46,
            "doSomething": "I'm IronMan, I'm watching TV now"
        }
    }
}

5、GraphQL客戶端

這一節咱們學習如何在客戶端中訪問 graphql 的接口。

1. 後端定義接口

咱們先在後端將接口開發完成,這裏跟前面差很少,但須要多一步,使用 express 向外暴露一個文件夾,供用戶訪問靜態資源文件:

這裏直接使用前一節的代碼啦~

// index.js  開發 graphql 接口
//...省略其餘
const schema = buildSchema(`
    type Hero {
        name: String
        age: Int
        doSomething(thing: String): String
    }
    type Query {
        getSuperHero(heroName: String!): Hero
    }
`)
const root = {
    getSuperHero: ({heroName}) => {
        // 這裏的操做 實際開發中經常用在請求數據庫
        const name = heroName
        const age = 46
        const doSomething = ({thing}) => {
            return `I'm ${name}, I'm ${thing} now`
        }
        return { name, age, doSomething }
    }
}
const app = express()
app.use('/graphql', graphqlHTTP({
    schema, rootValue: root, graphiql: true
}))
// 公開文件夾 使用戶訪問靜態資源
app.use(express.static('public'))
app.listen(3000)

這樣咱們就給前端頁面提供一個能夠訪問靜態資源的功能。

這裏還須要在根目錄建立一個 public 文件夾,並在文件夾中添加 index.html 文件,此時的目錄結構:

|-node_modules
|-public
|---index.html
|-index.js
|-package.json

2. 前端頁面請求

而後給 index.html 添加按鈕和事件綁定:

這裏的變量 query 是個字符串類型,定義查詢條件,在條件 GetSuperHero 中的參數,須要用 $ 符號來標識,並在實際查詢 getSuperHero 中,做爲參數的參數類型設置進來。

而後定義變量 variables ,指定屬性的值,以後經過 fetch 發起請求:

<button onclick="getData()">獲取數據</button>
<script>
function getData(){
    const query = `
        query GetSuperHero($heroName: String, $thing: String){
            getSuperHero(heroName: $heroName){
                name
                    age
                    doSomething(thing: $thing)
            }
        }
    `
    // 若是不須要其餘參數 至少要傳一個參數 不然會報錯
    // const query = `
    //     query GetSuperHero($heroName: String){
    //         getSuperHero(heroName: $heroName){
    //              name
    //         }
    //     }
    // `    
    const variables = {heroName: '鋼鐵俠', thing: 'watching TV'}

    fetch('./graphql', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify({
            query, variables
        })
    })
    .then(res => res.json())
    .then(json => {
        console.log(json)
    })
}
</script>

當咱們寫完之後,點擊 獲取數據 就會在控制檯打印下面的數據:

{
    "data":{
        "getSuperHero":{
            "name":"鋼鐵俠",
            "age":46,
            "doSomething": "I'm 鋼鐵俠, I'm watching TV now"
        }
    }
}

3. 注意點

  • 請求中的 query 參數須要對照好有 $ 符號的變量。

查詢語句 query GetSuperHero($heroName: String) 裏參數 $heroName 中的 heroName
查詢語句 getSuperHero(heroName: $heroName) 裏類型 $heroName 中的 heroName
變量 variables 中的 heroName 屬性;

這三個名稱須要同樣

  • 請求中須要將數據序列化操做
body: JSON.stringify({ query, variables })

6、使用Mutations修改數據

1. Mutation 使用

根據前面的學習,咱們知道,要作查詢操做,須要使用 Query 來聲明:

type Query {
    queryHero(heroName: String): String
}

當咱們要作修改操做,須要用到的是 Mutation :

type Mutation {
    createHero(heroName: String): String
}

若是 Mutation 中字段的形參是自定義類型,則類型須要用 input 標識:

const schema = buildSchema(`
    # 輸入類型 用 input 標識
    input HeroInput {
        name: String
        age: Int
    }
    # 查詢類型
    type Hero {
        name: String
        age: Int
    }
    type Mutation {
        createHero(heroName: String): Hero
        updateHero(heroName: String, hero: HeroInput): Hero
    }
`)

注意下:這裏須要至少定義一個 Query 否則 GraphiQL 會不顯示查詢:

type Query {
    hero: [Hero]
}

2. Mutation 使用案例

先建立一個 schema ,內容爲上一步【1. Mutation 使用】中定義的內容,這裏不重複寫。
而後模擬建立一個本地數據庫 localDb, 用於模擬存放添加的超級英雄數據:

const localDb = {}

接下來聲明 root 實現 schema 中的字段方法:

const root = {
    hero() {
        // 這裏須要轉成數組 由於前面定義了返回值是  [Hero]  類型
        let arr = []
        for(const key in localDb){
            arr.push(localDb[key])
        }
        return arr
    },
    createHero({ input }) {
        // 至關於數據庫的添加操做
        localDb[input.name] = input
        return localDb[input.name]
    },
    updateHero({ id, input }) {
        // 至關於數據庫的更新操做
        const update = Object.assign({}, localDb[id], input)
        localDb[id] = update
        return update
    }
}

最後配置 graphqlHTTP 方法和啓動服務器,這裏就很少重複咯。

最終代碼:

//...省略其餘
const schema = buildSchema(`
    # 輸入類型 用 input 標識
    input HeroInput {
        name: String
        age: Int
    }
    # 查詢類型
    type Hero {
        name: String
        age: Int
    }
    type Mutation {
        createHero(input: HeroInput): Hero 
        updateHero(id: ID!, input: HeroInput): Hero
    }
    # 須要至少定義一個 Query 不要GraphiQL會不顯示查詢
    type Query {
        hero: [Hero]
    }
`)

const localDb = {}

const root = {
    hero() {
        // 這裏須要轉成數組 由於前面定義了返回值是  [Hero]  類型
        let arr = []
        for(const key in localDb){
            arr.push(localDb[key])
        }
        return arr
    },
    createHero({ input }) {
        // 至關於數據庫的添加操做
        localDb[input.name] = input
        return localDb[input.name]
    },
    updateHero({ id, input }) {
        // 至關於數據庫的更新操做
        const update = Object.assign({}, localDb[id], input)
        localDb[id] = update
        return update
    }
}
//...省略其餘

如今咱們能夠啓動服務器,在 GraphiQL 上測試下效果了。

咱們是使用 mutationcreateHero 字段添加兩條數據:

mutation {
    createHero(input: {
        name: "鋼鐵俠"
        age: 40
    }){
        name
        age
    }
}
mutation {
    createHero(input: {
        name: "美國隊長"
        age: 41
    }){
        name
        age
    }
}

而後使用 queryhero 字段查詢添加的結果:

query {
    hero {
        name
        age
    }
}

這樣咱們就獲取到剛纔的添加結果:

{
    "data": {
        "hero": [
            {
                "name": "鋼鐵俠",
                "age": 40
            },
            {
                "name": "美國隊長",
                "age": 41
            }
        ]
  }
}

而後咱們開始更新數據,使用 mutationupdateHero 字段將 美國隊長age 值修改成 18:

mutation {
    updateHero(id: "美國隊長", input: {
        age: 18
    }){
        age
    }
}

再使用 queryhero 字段查詢下新的數據,會發現 美國隊長age 值已經更新爲 18:

{
    "data": {
        "hero": [
            {
                "name": "鋼鐵俠",
                "age": 40
            },
            {
                "name": "美國隊長",
                "age": 18
            }
        ]
    }
}

7、認證和中間件

咱們知道,修改數據的接口不能讓全部人隨意訪問,因此須要添加權限認證,讓有權限的人才能夠訪問。
express 中,能夠很簡單的使用中間件來將請求進行攔截,將沒有權限的請求過濾並返回錯誤提示。

中間件其實是一個函數,在接口執行以前,先攔截請求,再決定咱們是否接着往下走,仍是返回錯誤提示。

這在【6、使用Mutations修改數據】的最終代碼上,在添加這個中間件:

//... 省略其餘
const app = express()
const middleWare = (req, res, next) => {
    // 這裏是簡單模擬權限
    // 實際開發中 更多的是和後端進行 token 交換來判斷權限
    if(req.url.indexOf('/graphql') !== -1 && req.headers.cookie.indexOf('auth') === -1){
        // 向客戶端返回一個錯誤信息
        res.send(JSON.stringify({
            err: '暫無權限'
        }))
        return
    }
    next() // 正常下一步
}
// 註冊中間件
app.use(middleWare)

//... 省略其餘

這裏的權限判斷,只是簡單模擬,實際開發中,更多的是和後端進行 token 交換來判斷權限(或者其餘形式)。
咱們重啓服務器,打開 http://localhost:3000/graphql ,發現頁面提示錯誤了,由於 cookies 中沒有含有 auth 字符串。

若是這裏提示 TypeError: Cannot read property 'indexOf' of undefined ,能夠先不用管,由於瀏覽器中沒有 cookies 的緣由,其實前面的權限判斷邏輯須要根據具體業務場景判斷。

爲了方便測試,咱們在 chrome 瀏覽器控制檯的 application 下,手動設置一個含有 auth 字符串的一個 cookies ,只是測試使用哦。

設置完成後,咱們就能正常進入頁面。

8、ConstructingTypes

在前面的介紹中,咱們要建立一個 schema 都是使用 buildSchema 方法來定義,但咱們也可使用另一種定義方式。
就是這裏要學習使用的構造函數 graphql.GraphQLObjectType 定義,它有這麼幾個優勢和缺點:

  • 優勢:報錯提醒更直觀,結構更清晰,更便於維護。
  • 缺點:代碼量上升。

1. 定義type(類型)

這裏先將前面定義的 Hero 類型進行改造:

const graphql = require('graphql') // 須要引入
const HeroType = new graphql.GraphQLObjectType({
    name: 'Hero',
    fields: {
        name:{ type: graphql.GraphQLString },
        age:{ type: graphql.GraphQLInt },
    }
})

graphql6

二者區別在於:

區別 buildSchema graphql.GraphQLObjectType
參數類型 字符串 對象
類名 跟在 type 字符後面,這裏是 type Hero 在參數對象的 name 屬性上
屬性定義 定義在類型後,鍵值對形式 定義在參數對象 fields 屬性中,值爲對象,每一個屬性名爲鍵名,值也是對象,其中 type 屬性的值爲 graphql 中的屬性,下面會補充

補充:
fields 屬性中的子屬性的類型一般有:

  • graphql.GraphQLString
  • graphql.GraphQLInt
  • graphql.GraphQLBoolean

....

即在 GraphQL後面跟上基本類型名稱。

2. 定義query(查詢)

定義查詢的時候,跟以前相似,能夠參照下面對比圖理解,這裏比較不一樣的是,多了個 resolve 的方法,這個方法是用來執行處理查詢的邏輯,其實就是以前的 root 中的方法。

const QueryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
        // 一個個查詢方法
        getSuperHero: {
            type: HeroType,
            args: {
                heroName: { type: graphql.GraphQLString }
            },
            // 方法實現 查詢的處理函數
            resolve: function(_, { heroName }){
                const name = heroName
                const age = 18
                return { name, age }
            }
        }
    }
})

graphql8

3. 建立 schema

建立的時候只需實例化而且將參數傳入便可:

// step3 構造 schema
const schema = new graphql.GraphQLSchema({ query: QueryType})

最後使用也是和前面同樣:

const app = express()

app.use('/graphql', graphqlHTTP({
    schema,
    graphiql: true
}))
app.listen(3000)

9、與數據庫結合實戰

咱們試着使用前面所學的內容,開發一個簡單的實踐項目:
經過 GraphiQL 頁面,往 Mongodb 中插入和更新數據,主要用到【6、使用Mutations修改數據】章節的操做。

1. 搭建並啓動本地 Mongodb 數據庫

首先咱們能夠到 Mongodb 官網 選擇對應平臺和版本下載安裝。

下載安裝步驟,能夠參考 mongoDB下載、安裝和配置,這裏就很少介紹喲~~

安裝完成後,咱們打開兩個終端,分別執行下面兩行命令:

// 終端1  啓動數據庫
mongod --dbpath c:\leo\app\mongodb\data\db

// 終端2  進入數據庫命令行操做模式
mongo

2. 鏈接數據庫,建立 Schema 和 Model

首先咱們新建一個文件 db.js ,並 npm install mongoose 安裝 mongoose ,而後寫入下面代碼,實現鏈接數據庫

const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')
const mongoose = require('mongoose')

const DB_PATH = 'mongodb://127.0.0.1:27017/hero_table'
const connect = () => {
    // 鏈接數據庫
    mongoose.connect(DB_PATH)
    // 鏈接斷開
    mongoose.connection.on('disconnected', () => {
        mongoose.connect(DB_PATH)
    })
    // 鏈接失敗
    mongoose.connection.on('error', err => {
        console.error(err)
    })
    // 鏈接成功
    mongoose.connection.on('connected', async () => {
        console.log('Connected to MongoDB connected', DB_PATH)
    })  
}
connect()

而後建立 SchemaModel

let HeroSchema = new mongoose.Schema({
    name: String,
    age: Number
})
let HeroModel = mongoose.model('hero',HeroSchema, 'hero_table')

3. 聲明查詢語句

這一步,仍是先使用【6、使用Mutations修改數據】章節的操做邏輯,也就是先用字符串建立查詢,而不使用 GraphQLObjectType 建立:

const schema = buildSchema(`
    # 輸入類型 用 input 標識
    input HeroInput {
        name: String
        age: Int
    }
    # 查詢類型
    type Hero {
        name: String
        age: Int
    }
    type Mutation {
        createHero(input: HeroInput): Hero 
        updateHero(hero: String!, input: HeroInput): Hero
    }
    # 須要至少定義一個 Query 不要GraphiQL會不顯示查詢
    type Query {
        hero: [Hero]
    }
`)

這邊案例有稍做修改

4. 實現添加數據和更新數據的邏輯

這邊處理添加數據和更新數據的邏輯,就要修改以前聲明的 root 的操做內容了:

const root = {
    hero() {
        return new Promise( (resolve, reject) => {
            HeroModel.find((err, res) => {
                if(err) {
                    reject(err)
                    return
                }
                resolve(res)
            })
        })
    },
    createHero({ input }) {
        // 實例化一個Model
        const { name, age } = input
        const params = new HeroModel({ name, age })
        return new Promise( (resolve, reject) => {
            params.save((err, res) => {
                if(err) {
                    reject(err)
                    return
                }
                resolve(res)
            })
        })
    },
    updateHero({ hero, input }) {
        const { age } = input
        return new Promise ((resolve, reject) => {
            HeroModel.update({name: hero}, {age}, (err, res) => {
                if(err) {
                    reject(err)
                    return
                }
                resolve(res)
            })
        })
    }
}

5. 模擬測試

最後咱們在 GraphiQL 頁面上模擬測試一下,首先添加兩個英雄,鋼鐵俠和美國隊長,並設置他們的 age / name 屬性:

mutation {
    createHero(input: {
        name: "鋼鐵俠"
        age: 40
    }){
        name
        age
    }
}
mutation {
    createHero(input: {
        name: "美國隊長"
        age: 20
    }){
        name
        age
    }
}

頁面和接口沒有報錯,說明咱們添加成功,數據庫中也有這兩條數據了:

graphql10

在測試下查詢:

query {
    hero {
        name
        age
    }
}

graphql11

查詢也正常,接下來測試下更新,將美國隊長的 age 修改成 60:

mutation {
    updateHero(hero: "美國隊長", input: {
        age: 60
    }){
        age
    }
}

graphql12

到這一步,咱們也算是將這個練習作完了。

總結

  • GraphQL 是一種 API 的查詢語言,是 REST API 的替代品。
  • GraphQL 可使用一個請求,獲取全部想要的數據。
  • 建立查詢的方式有兩種:使用 buildSchema 或者 GraphQLObjectType
  • 查詢操做用 Query,修改操做用 Mutations
  • 查詢類型用 type ,輸入類型用 input

其實 GraphQL 仍是很簡單好用的呢~~~


本文首發在 pingan8787我的博客,如需轉載請保留我的介紹
相關文章
相關標籤/搜索