在Apollo/GraphQL中,除了mutations和queries,还有一种操作类型称为subscriptions。Subscriptions允许客户端通过WebSocket与服务器进行实时双向通信。
下面是一个使用Apollo-Server和Apollo-Client的示例,展示如何在Apollo/GraphQL中使用subscriptions:
首先,安装所需的依赖项:
npm install apollo-server apollo-client graphql graphql-subscriptions subscriptions-transport-ws
然后,创建一个Apollo-Server,配置它支持subscriptions:
// server.js
const { ApolloServer, PubSub } = require('apollo-server');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');
const pubsub = new PubSub();
const server = new ApolloServer({
typeDefs,
resolvers,
context: { pubsub },
});
// 启动Apollo-Server
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
// 创建一个SubscriptionServer
new SubscriptionServer(
{
execute,
subscribe,
schema: server.schema,
onConnect: () => console.log('Client connected to WebSocket'),
onDisconnect: () => console.log('Client disconnected from WebSocket'),
},
{
server: server.httpServer,
path: server.graphqlPath,
}
);
});
接下来,创建一个GraphQL模式和解析器:
// schema.js
const { gql } = require('apollo-server');
const typeDefs = gql`
type Message {
id: ID!
content: String!
}
type Query {
messages: [Message]
}
type Mutation {
sendMessage(content: String!): Message
}
type Subscription {
newMessage: Message
}
`;
module.exports = typeDefs;
// resolvers.js
let messages = [];
const resolvers = {
Query: {
messages: () => messages,
},
Mutation: {
sendMessage: (_, { content }, { pubsub }) => {
const newMessage = { id: messages.length + 1, content };
messages.push(newMessage);
// 发布新消息到订阅频道
pubsub.publish('NEW_MESSAGE', { newMessage });
return newMessage;
},
},
Subscription: {
newMessage: {
subscribe: (_, __, { pubsub }) => pubsub.asyncIterator('NEW_MESSAGE'),
},
},
};
module.exports = resolvers;
最后,创建一个Apollo-Client来连接到Apollo-Server并订阅新消息:
// client.js
const { ApolloClient, InMemoryCache, gql } = require('@apollo/client');
const { WebSocketLink } = require('@apollo/client/link/ws');
const { getMainDefinition } = require('@apollo/client/utilities');
const { split } = require('@apollo/client');
// 创建WebSocket链接
const wsLink = new WebSocketLink({
uri: 'ws://localhost:4000/graphql',
options: {
reconnect: true,
},
});
// 创建HTTP链接
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql',
});
// 使用split函数将订阅操作发送到WebSocket链接,其他操作发送到HTTP链接
const link = split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink
);
// 创建Apollo-Client
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
});
// 定义订阅新消息的GraphQL查询
const NEW_MESSAGE_SUBSCRIPTION = gql`
subscription {
newMessage {
id
content
}
}
`;
// 订阅新消息
const subscription = client.subscribe({ query: NEW_MESSAGE_SUBSCRIPTION });
// 处理新消息的响应
subscription.subscribe({
next({ data }) {
console.log('Received new message:', data.newMessage);
},
error(error) {
console.error('Subscription error:', error);
},
});
这是一个简单的Apollo/GraphQL示例,其中包含了mutations、queries和subscriptions,以展示如何在Apollo/GraphQL中处理既不是mutations也不是queries的操作。希望对你有所帮助!