在 Express 4 使用 GraphQL 查詢語言

環境

  • macOS

建立專案

建立專案。

1
2
mkdir graphql-express
npm install --save graphql express-graphql express

建立資料結構

新增 GraphQLSchema.js 檔:

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
62
63
64
65
66
67
68
69
70
const { buildSchema } = require('graphql');

exports.schema = buildSchema(`
type User {
id: ID!
name: String!
posts: [Post!]!
}

type Post {
id: ID!
user: User!
title: String!
}

type Query {
users: [User!]!
posts: [Post!]!
}
`);

const users = {
1: {
id: 1,
name: 'Memo Chou',
},
};

const posts = {
1: {
id: 1,
user_id: 1,
title: 'Post 1',
},
2: {
id: 2,
user_id: 1,
title: 'Post 2',
},
};

class GraphQLUser {
constructor({ id, name }) {
this.id = id;
this.name = name;
}

posts() {
return Object.keys(posts)
.map(id => new GraphQLPost(posts[id]))
.filter(post => post.user_id === this.id);
}
}

class GraphQLPost {
constructor({ id, user_id, title }) {
this.id = id;
this.user_id = user_id;
this.title = title;
}

user() {
return new GraphQLUser(users[this.user_id]);
}
}

exports.rootValue = {
users: () => Object.keys(users).map(id => new GraphQLUser(users[id])),
posts: () => Object.keys(posts).map(id => new GraphQLPost(posts[id])),
};

建立伺服

新增 server.js 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const express = require('express');
const graphqlHTTP = require('express-graphql');

const { schema, rootValue } = require('./GraphQLSchema');

const app = express();

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

app.listen(3000);

啟動服務

1
node server.js

執行查詢

http://localhost:3000/graphql 執行查詢:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
users {
name
posts {
title
user {
name
posts {
title
user {
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"data": {
"users": [
{
"name": "Memo Chou",
"posts": [
{
"title": "Post 1",
"user": {
"name": "Memo Chou",
"posts": [
{
"title": "Post 1",
"user": {
"id": "1",
"name": "Memo Chou"
}
},
{
"title": "Post 2",
"user": {
"id": "1",
"name": "Memo Chou"
}
}
]
}
},
{
"title": "Post 2",
"user": {
"name": "Memo Chou",
"posts": [
{
"title": "Post 1",
"user": {
"id": "1",
"name": "Memo Chou"
}
},
{
"title": "Post 2",
"user": {
"id": "1",
"name": "Memo Chou"
}
}
]
}
}
]
}
]
}
}

參考資料