github的graphql使用

2020/8/2 graphql

# 变量(Variables)

  • 变量以 $ 开头, Int 为类型 , 为是否必填
# $repo 为变量名

query($repo:Int!) {
  viewer {
    # 用户名 -> 注释
    name #  -> 字段
     repositories(last: $repo) { # 在操作中使用变量 $repo
       nodes {
         name
       }
     }
   }
}

// query variables
variables {
   "repo": 3
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 默认变量(Default variables)
// "chengzao" 为 $user 的默认值
query MyQuery($user: String = "chengzao") {
  user(login: $user) {
    login
  }
}
1
2
3
4
5
6

# 操作名称(Operation name)

# MyQuery 为操作名
query MyQuery {
  viewer {
    login
  }
}
1
2
3
4
5
6

# 别名(Aliases)

query MyPaginationQuery($pageSize: Int = 10) {
  viewer {
    # startsRepos 为 starredRepositories 的别名
    startsRepos: starredRepositories(first: $pageSize) {
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
      edges {
        cursor
        node {
          id
          name
        }
      }
      totalCount
    }
  }
}

# 返回数据
{
  "data": {
    "viewer": {
      "startsRepo": {
        "pageInfo": {
          "endCursor": "xxx",
          "hasNextPage": true,
          "hasPreviousPage": false,
          "startCursor": "xxx"
        },
        "edges": [
          {
            "cursor": "xxx",
            "node": {
              "id": "xxx",
              "name": "nvm"
            }
          },
        ],
        "totalCount": 17
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 片段(Fragments)

query MyPaginationQuery($pageSize: Int = 10) {
  viewer {
    startsRepos: starredRepositories(first: $pageSize) {
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
      totalCount
      ...nodes
    }
  }
}

# https://graphql.cn/learn/schema/#interfaces
# StarredRepositoryConnection 为 github graphql 中定义好的类型
fragment nodes on StarredRepositoryConnection {
   repos: edges {
      cursor
      node {
        id
        name
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  • 在片段内使用变量
query MyPaginationQuery($pageSize: Int = 10) {
  viewer {
    ...viewer
  }
}

# viewer
fragment viewer on User{
   startsRepos: starredRepositories(first: $pageSize) {
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
      totalCount
      ...nodes
    }
}


# nodes
fragment nodes on StarredRepositoryConnection {
   repos: edges {
      cursor
      node {
        id
        name
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 指令(Directives)

  • include包含此字段
query MyQuery($showStatus: Boolean!) {
  viewer {
    login
    status @include(if: $showStatus) {
      emoji
    }
  }
}

# query variables
{
  "showStatus": true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • skip跳过此字段
query MyQuery($showStatus: Boolean!) {
  viewer {
    login
    status @skip(if: $showStatus) {
      emoji
    }
    id
  }
}

# query variables
{
  "showStatus": true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 变更(Mutations)

  • 约定规范任何导致写入的操作都应该显式通过变更(mutation)来发送
query FindIssueID {
  repository(owner:"octocat", name:"Hello-World") {
    issue(number:349) {
      id
    }
  }
}

mutation AddReactionToIssue {
  addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 多个参数
mutation($myVar:AddReactionInput!) {
  addReaction(input:$myVar) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}

# query variables
# https://docs.github.com/cn/graphql/reference/input-objects#addreactioninput
variables {
  "myVar": {
    "subjectId":"MDU6SXNzdWUyMTc5NTQ0OTc=",
    "content":"HOORAY"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 分页(Pagination)

  • github分页query
query MyPaginationQuery($cursorNo: String!, $pageSize: Int=10) {
  viewer {
    starredRepositories(first: $pageSize, after: $cursorNo) {
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
      edges {
        cursor
        node {
          id
          name
        }
      }
      totalCount
    }
  }
}

# query variables
# cursorNo: 传入返回数据中的 pageInfo.startCursor / pageInfo.endCursor
{
  "cursorNo": "xxx",
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# nodejs 示例

const axios = require('axios')

// ACCESS_TOKEN -> https://github.com/settings/tokens
// .env -> ACCESS_TOKEN=axxxx54

require("dotenv").config();
const TOKEN = process.env.ACCESS_TOKEN;
const GH_API = "https://api.github.com/graphql";

function request (query, variables, headers = {}) {
  return axios({
    url: GH_API,
    method: "post",
    headers:{
      Authorization: `bearer ${TOKEN}`,
      ...headers
    },
    data:{
      query,
      variables
    },
  });
}

const query = `
  query MyPaginationQuery($pageSize: Int = 10) {
    viewer {
      startsRepos: starredRepositories(first: $pageSize) {
        pageInfo {
          endCursor
          hasNextPage
          hasPreviousPage
          startCursor
        }
        totalCount
        ...nodes
      }
    }
  }

  fragment nodes on StarredRepositoryConnection {
    repos: edges {
        cursor
        node {
          id
          name
        }
      }
  }
`

const variables = {
  pageSize: 5
}

const data = async () => {
  const res = await request(query, variables)
  console.log(JSON.stringify(res.data, 0 ,2));
}

data()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# github 登录授权