Skip to main content

GraphQL 实践

GraphQL 示例

info

这个 Markdown 文档展示了如何在 Node.js 环境下使用 Apollo Server 搭建 GraphQL 服务器,并使用 Apollo Client 在客户端进行查询、变更和订阅。记得在运行这些代码之前安装所有必要的依赖。

服务器端:Node.js 和 Apollo Server

安装依赖

npm install apollo-server graphql

创建服务器 (server.js)

const { ApolloServer, gql, PubSub } = require("apollo-server");

// 定义Schema
const typeDefs = gql`
type Query {
user(id: ID!): User
}

type Mutation {
addUser(name: String!): User
}

type Subscription {
userAdded: User
}

type User {
id: ID!
name: String!
}
`;

const users = {}; // 简单的用户存储
let nextId = 1;
const pubsub = new PubSub();

// 定义解析器
const resolvers = {
Query: {
user: (_, { id }) => users[id],
},
Mutation: {
addUser: (_, { name }) => {
const id = nextId++;
const user = { id, name };
users[id] = user;
pubsub.publish("USER_ADDED", { userAdded: user }); // @NOTE: 'USER_ADDED' 为订阅时间的名称, 其后是发布数据
return user;
},
},
Subscription: {
userAdded: {
subscribe: () => pubsub.asyncIterator(["USER_ADDED"]),
},
},
};

// 创建Apollo Server实例
const server = new ApolloServer({ typeDefs, resolvers });

// 启动服务器
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});

客户端:Apollo Client

安装依赖

npm install @apollo/client graphql subscriptions-transport-ws

创建客户端 (client.js)

import {
ApolloClient,
InMemoryCache,
gql,
HttpLink,
split,
} from "@apollo/client";
import { WebSocketLink } from "@apollo/client/link/ws";
import { getMainDefinition } from "@apollo/client/utilities";

// HTTP连接
const httpLink = new HttpLink({
uri: "http://localhost:4000/graphql",
});

// WebSocket连接
const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`,
options: {
reconnect: true,
},
});

// 根据操作类型分割链接
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
// 当结果为 true 时,使用 wsLink, false -> httpLink, 订阅操作的类型是 {kind: 'OperationDefinition', operation: 'subscription'}
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
httpLink
);

// 创建Apollo Client实例
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});

// 查询示例
client
.query({
query: gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
`,
variables: { id: "1" },
})
.then((result) => console.log(result));

// 变更示例
client
.mutate({
mutation: gql`
mutation AddUser($name: String!) {
addUser(name: $name) {
id
name
}
}
`,
variables: { name: "New User" },
})
.then((result) => console.log(result));

// 订阅示例
client
.subscribe({
query: gql`
subscription {
userAdded {
id
name
}
}
`,
})
.subscribe({
next(data) {
console.log(data);
},
error(err) {
console.error("err", err);
},
});