我们已经有了我们的解析器 和 数据源 准备就绪,但它们还不知道如何协同工作。
Apollo Server 是所有之前构建的元素(模式、解析器 和 数据源)完美协调的地方。
在server/src/index.js
中,我们在第一部分配置了我们的 Apollo Server,现在我们可以用 解析器 替换我们的模拟。
让我们删除 mocks
对象,以及 ApolloServer
构造函数中所有模拟设置以及模拟函数的导入。
const { ApolloServer } = require('@apollo/server');const { startStandaloneServer } = require('@apollo/server/standalone');- const { addMocksToSchema } = require('@graphql-tools/mock');- const { makeExecutableSchema } = require('@graphql-tools/schema');const typeDefs = require('./schema');- const mocks = {- Query: () => ({- tracksForHome: () => [...new Array(6)],- }),- Track: () => ({- id: () => 'track_01',- title: () => 'Astro Kitty, Space Explorer',- author: () => {- return {- name: 'Grumpy Cat',- photo: 'https://res.cloudinary.com/dety84pbu/image/upload/v1606816219/kitty-veyron-sm_mctf3c.jpg',- };- },- thumbnail: () => 'https://res.cloudinary.com/dety84pbu/image/upload/v1598465568/nebula_cat_djkt9r.jpg',- length: () => 1210,- modulesCount: () => 6,- }),- };async function startApolloServer() {const server = new ApolloServer({- schema: addMocksToSchema({- schema: makeExecutableSchema({ typeDefs }),- mocks,- }),});const { url } = await startStandaloneServer(server);console.log(`🚀 Server is running📭 Query at ${url}`);}startApolloServer();
我们应该最终得到类似这样的东西
const { ApolloServer } = require("@apollo/server");const { startStandaloneServer } = require("@apollo/server/standalone");const typeDefs = require("./schema");async function startApolloServer() {const server = new ApolloServer({});const { url } = await startStandaloneServer(server);console.log(`🚀 Server is running📭 Query at ${url}`);}startApolloServer();
接下来,让我们在顶部导入我们的 resolvers
文件。
const resolvers = require("./resolvers");
然后将 typeDefs
和 resolvers
添加到 ApolloServer
选项中。
const server = new ApolloServer({typeDefs,resolvers,});
这样就完成了 解析器 的处理。
接下来,就在我们的 resolvers
导入下面,我们将要求 track-api
,我们的 数据源 文件(扩展 RESTDataSource
),并将其称为 TrackAPI
(注意 PascalCase 约定,因为我们在这里处理类)。
const TrackAPI = require("./datasources/track-api");
要将我们的服务器与我们的 TrackAPI
连接起来,我们将跳到 startStandaloneServer
函数。此函数接受第二个 参数,它是用于配置服务器选项的对象。
const { url } = await startStandaloneServer(server, {// TODO: configure server options});
在这里,我们将定义一个 context
函数,该函数返回一个所有 解析器 将共享的对象: contextValue
(我们之前提到的第三个位置 参数!)。
让我们设置一个 context
属性作为异步函数,该函数返回一个对象。
const { url } = await startStandaloneServer(server, {context: async () => {// this object becomes our resolver's contextValue, the third positional argumentreturn {// TODO};},});
请记住,我们想要从 contextValue
参数访问 dataSources.trackAPI
(及其方法)在我们的 解析器 中。因此,让我们返回一个允许我们执行此操作的对象!
我们将在对象内部设置一个 dataSources
属性,该属性设置为另一个对象。此对象将有一个 trackAPI
键,该键返回我们之前导入的 TrackAPI
的一个实例 数据源 类。
const { url } = await startStandaloneServer(server, {context: async () => {return {dataSources: {trackAPI: new TrackAPI(),},};},});
注意: 我们的 解析器 函数期望在它们的 contextValue
上找到 dataSources.trackAPI
,这就是我们在服务器中在这里定义了名为 dataSources
的属性的原因。这个特定的名称不是必需的 - 我们选择 dataSources
作为一种约定。您可以为该属性命名任何您喜欢的名称,但请确保您更新您的 解析器 函数以访问相同的属性。
还有一件事!要利用 RESTDataSource
的缓存功能,我们需要将服务器的缓存传递给我们的 TrackAPI
。
在我们返回 contextValue
对象之前,让我们从 server
中解构 cache
属性。然后,我们将一个对象传递给 TrackAPI
类,该对象包含该 cache
属性。
const { url } = await startStandaloneServer(server, {context: async () => {const { cache } = server;return {dataSources: {trackAPI: new TrackAPI({ cache }),},};},});
这是我们的服务器配置完成后将是什么样子
const { ApolloServer } = require("@apollo/server");const { startStandaloneServer } = require("@apollo/server/standalone");const typeDefs = require("./schema");const resolvers = require("./resolvers");const TrackAPI = require("./datasources/track-api");async function startApolloServer() {const server = new ApolloServer({ typeDefs, resolvers });const { url } = await startStandaloneServer(server, {context: async () => {const { cache } = server;return {dataSources: {trackAPI: new TrackAPI({ cache }),},};},});console.log(`🚀 Server is running📭 Query at ${url}`);}startApolloServer();
要详细了解 ApolloServer
可以接收的选项,查看文档。
我们有一个名为 SpaceCatsAPI
的类,它实现了一个 RESTDataSource
。我们需要访问此类的实例,我们将称之为 spaceCatsAPI
,从我们的解析器中。在下面配置服务器,以便我们的解析器可以通过它们在 contextValue
参数上接收的 dataSources.spaceCatsAPI
属性访问此类。(注意,区分大小写!)
context
函数返回 dataSources
对象?我们的服务器现在已完全配置为与实时数据一起使用。
分享您对本课的疑问和意见
您的反馈将帮助我们改进!如果您遇到困难或困惑,请告诉我们,我们会帮助您。所有评论都是公开的,必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被删除。
您需要一个 GitHub 帐户才能在下面发帖。没有帐户? 改为在我们的 Odyssey 论坛中发帖。