使用 faker.js 真实地模拟你的 GraphQL 服务器
有时你的 GraphQL 服务器需要使用尚未实现或暂时不可用的 API。在这种情况下,模拟似乎是正确的做法,但维护良好的模拟数据很困难,最终导致我们的应用中到处都是“乱码”。
faker.js
faker.js是一个可以在 Node.js 或浏览器中生成虚假数据的库。它提供了很多方法来生成常见数据,例如:
- 名字
- 地址
- 手机
- 图片
- 公司
- ...
即使对于...Lorem ipsum!
其他工具
我们将使用Koa来创建服务器。它是“Express 团队设计的全新 Web 框架”。实际上,它采用了不同的中间件实现,并且比 Express 包含的内容更少。如果您想了解更多信息,可以访问 Koa 的仓库进行比较。
对于 GraphQL 实现,我们将使用Apollo Server。它似乎是最流行的 GraphQL 服务器实现,并且与 Koa 非常契合,因为存在一个apollo-server-koa包,并且已由 Apollo Server 团队实现。
最后,我们将使用众所周知的cross-env包来设置环境变量,无论您使用的是什么平台。
设置服务器
首先,我们创建一个具有以下结构的文件夹:
.
├── package.json
└── src
└── index.js
在本文中我们将使用,yarn
但您npm
也可以使用。使用以下init
命令初始化 package.json:
yarn init
安装以下依赖项:
yarn add apollo-server-koa cross-env faker graphql koa
添加start
执行我们src/index.js
文件的脚本:
{
"scripts": {
"start": "node src/index.js"
}
}
在src/index.js
文件中我们实例化一个新的 Koa 应用程序:
const Koa = require('koa');
const app = new Koa();
app.listen({port: 4000}, () =>
console.log(`🚀 Server ready at http://localhost:4000`),
);
运行start
脚本。您应该console.log
在控制台输出中看到上述示例中的消息。
创建 GraphQL 端点
现在是时候实现我们的 GraphQL 端点了。假设我们目前还没有实现某个 API。该 API 需要公开一个包含姓氏和名字的人员列表。我们将定义一个 schema,并使其能够在/graphql
端点上访问apollo-server-koa
。
导入ApolloServer
和gql
来自apollo-server-koa
:
const {ApolloServer, gql} = require('apollo-server-koa');
我们定义一个查询,返回 Person 列表和 Person 类型本身:
const typeDefs = gql`
type Person {
lastname: String
firstname: String
}
type Query {
persons: [Person]
}
`;
由于该 API 尚不存在,我们会抛出一个错误来通知用户他无法使用此查询:
const resolvers = {
Query: {
persons: () => {
throw Error('Not yet implemented');
},
},
};
我们使用我们的类型定义和查询解析器实例化一个 Apollo 服务器:
const server = new ApolloServer({
typeDefs,
resolvers,
});
最后将之前创建的GraphQL中间件应用到Koa应用中:
server.applyMiddleware({app});
如果您现在使用该命令启动服务器yarn start
并在浏览器中打开 URL ,您应该会看到GraphQL IDEhttp://localhost:4000/graphql
的漂亮界面。
如果您键入查询来检索人员列表及其数据:
{
persons {
firstname,
lastname
}
}
这应该会导致出现以下错误:
{
"errors": [
{
"message": "Not yet implemented",
}
]
}
使用 faker.js 进行模拟
这个错误并非预期结果。我们希望在服务器被模拟时,能够获得随机的真实数据。为了实现这一点,我们需要用另一个生成虚假数据的解析器来覆盖默认的解析器(它会抛出错误)。
为此,我们将设置NODE_ENV
环境变量来mock
确定 Apollo 服务器应遵循的行为。我们将通过mock
在我们的脚本中添加一个脚本来实现这一点,该脚本使用并调用该脚本package.json
来设置变量:NODE_ENV
cross-env
start
{
"scripts": {
"start": "node src/index.js",
"mock": "cross-env-shell NODE_ENV=mock yarn start"
}
}
Apollo 服务器的mocks
选项中有一个属性,可以接受布尔值或带有模拟解析器的对象。首先,我们将其设置true
为:NODE_ENV
mock
const server = new ApolloServer({
typeDefs,
resolvers,
mocks: process.env.NODE_ENV === 'mock' ? true : false,
});
在此步骤中,如果您在 GraphQL IDE 中重新执行查询,您将得到第一个结果:
{
"data": {
"persons": [
{
"firstname": "Hello World",
"lastname": "Hello World"
},
{
"firstname": "Hello World",
"lastname": "Hello World"
}
]
}
}
这听起来不错,但不太现实。要添加伪造器,我们需要实现自己的模拟解析器并将其传递给 Apollo 服务器。在模拟解析器中,Query 属性必须是一个返回包含解析器定义的对象的函数。在我们的查询解析器中,persons
我们返回一个包含两个人的数组。
faker.js
方法在命名空间中组织。我们将使用name
包含如下方法的命名空间:
- 名
- 姓
- 职称
- 标题
- ...
你猜对了,我们将使用firstName
和lastName
方法为我们的两个人生成随机数据:
const mockResolvers = {
Query: () => ({
persons: () => [
{
firstname: name.firstName(),
lastname: name.lastName(),
},
{
firstname: name.firstName(),
lastname: name.lastName(),
},
],
}),
};
// ...
const server = new ApolloServer({
typeDefs,
resolvers,
mocks: process.env.NODE_ENV === 'mock' ? mockResolvers : false,
});
在 GraphQL IDE 中执行查询,您现在会得到如下数据:
{
"data": {
"persons": [
{
"firstname": "Mélissa",
"lastname": "Mathieu"
},
{
"firstname": "Camille",
"lastname": "Richard"
}
]
}
}
奖金
以下是我用来为模拟解析器生成随机大小数组的方法:
const randomArray = (min, max, callback) => {
const size = random.number({min, max});
return Array.from({length: size}, callback);
};
我们可以像这样使用这种方法重构以前的解析器:
const mockResolvers = {
Query: () => ({
persons: () =>
randomArray(2, 6, () => ({
firstname: name.firstName(),
lastname: name.lastName(),
})),
}),
};
我创建了一个存储库,其中包含本文介绍的所有资源。欢迎反馈🙏如有任何疑问,请在推特上@YvonnickFrin!
鏂囩珷鏉ユ簮锛�https://dev.to/yvonnickfrin/mock-your-graphql-server-realistically-with-faker-js-25oo