7. 连接服务器端的点
2m

我们已经有了我们的 准备就绪,但它们还不知道如何协同工作。

是所有之前构建的元素(模式、)完美协调的地方。

Hand-drawn illustration depicting a GraphQL server juggling three components: the schema, resolver function and data sources

server/src/index.js中,我们在第一部分配置了我们的 ,现在我们可以用 替换我们的模拟。

让我们删除 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");

然后将 typeDefsresolvers 添加到 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 argument
return {
// 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 论坛中发帖。