使用 faker.js 真实地模拟你的 GraphQL 服务器

2025-06-11

使用 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
Enter fullscreen mode Exit fullscreen mode

在本文中我们将使用,yarn但您npm也可以使用。使用以下init命令初始化 package.json:

yarn init
Enter fullscreen mode Exit fullscreen mode

安装以下依赖项:

yarn add apollo-server-koa cross-env faker graphql koa
Enter fullscreen mode Exit fullscreen mode

添加start执行我们src/index.js文件的脚本:

{
  "scripts": {
    "start": "node src/index.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

src/index.js文件中我们实例化一个新的 Koa 应用程序:

const Koa = require('koa');

const app = new Koa();

app.listen({port: 4000}, () =>
  console.log(`🚀 Server ready at http://localhost:4000`),
);
Enter fullscreen mode Exit fullscreen mode

运行start脚本。您应该console.log在控制台输出中看到上述示例中的消息。

创建 GraphQL 端点

现在是时候实现我们的 GraphQL 端点了。假设我们目前还没有实现某个 API。该 API 需要公开一个包含姓氏和名字的人员列表。我们将定义一个 schema,并使其能够在/graphql端点上访问apollo-server-koa

导入ApolloServergql来自apollo-server-koa

const {ApolloServer, gql} = require('apollo-server-koa');
Enter fullscreen mode Exit fullscreen mode

我们定义一个查询,返回 Person 列表和 Person 类型本身:

const typeDefs = gql`
  type Person {
    lastname: String
    firstname: String
  }

  type Query {
    persons: [Person]
  }
`;
Enter fullscreen mode Exit fullscreen mode

由于该 API 尚不存在,我们会抛出一个错误来通知用户他无法使用此查询:

const resolvers = {
  Query: {
    persons: () => {
      throw Error('Not yet implemented');
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

我们使用我们的类型定义和查询解析器实例化一个 Apollo 服务器:

const server = new ApolloServer({
  typeDefs,
  resolvers,
});
Enter fullscreen mode Exit fullscreen mode

最后将之前创建的GraphQL中间件应用到Koa应用中:

server.applyMiddleware({app});
Enter fullscreen mode Exit fullscreen mode

如果您现在使用该命令启动服务器yarn start并在浏览器中打开 URL ,您应该会看到GraphQL IDEhttp://localhost:4000/graphql的漂亮界面

GraphQL IDE

如果您键入查询来检索人员列表及其数据:

{
  persons {
    firstname,
    lastname
  }
}
Enter fullscreen mode Exit fullscreen mode

这应该会导致出现以下错误:

{
  "errors": [
        {
            "message": "Not yet implemented",
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

使用 faker.js 进行模拟

这个错误并非预期结果。我们希望在服务器被模拟时,能够获得随机的真实数据。为了实现这一点,我们需要用另一个生成虚假数据的解析器来覆盖默认的解析器(它会抛出错误)。

为此,我们将设置NODE_ENV环境变量来mock确定 Apollo 服务器应遵循的行为。我们将通过mock在我们的脚本中添加一个脚本来实现这一点,该脚本使用并调用该脚本package.json来设置变量NODE_ENVcross-envstart

{
  "scripts": {
    "start": "node src/index.js",
    "mock": "cross-env-shell NODE_ENV=mock yarn start"
  }
}
Enter fullscreen mode Exit fullscreen mode

Apollo 服务器的mocks选项中有一个属性,可以接受布尔值或带有模拟解析器的对象。首先,我们将其设置trueNODE_ENVmock

const server = new ApolloServer({
  typeDefs,
  resolvers,
  mocks: process.env.NODE_ENV === 'mock' ? true : false,
});
Enter fullscreen mode Exit fullscreen mode

在此步骤中,如果您在 GraphQL IDE 中重新执行查询,您将得到第一个结果:

{
  "data": {
    "persons": [
      {
        "firstname": "Hello World",
        "lastname": "Hello World"
      },
      {
        "firstname": "Hello World",
        "lastname": "Hello World"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

这听起来不错,但不太现实。要添加伪造器,我们需要实现自己的模拟解析器并将其传递给 Apollo 服务器。在模拟解析器中,Query 属性必须是一个返回包含解析器定义的对象的函数。在我们的查询解析器中,persons我们返回一个包含两个人的数组。

faker.js方法在命名空间中组织。我们将使用name包含如下方法的命名空间:

  • 职称
  • 标题
  • ...

你猜对了,我们将使用firstNamelastName方法为我们的两个人生成随机数据:

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,
});
Enter fullscreen mode Exit fullscreen mode

在 GraphQL IDE 中执行查询,您现在会得到如下数据:

{
  "data": {
    "persons": [
      {
        "firstname": "Mélissa",
        "lastname": "Mathieu"
      },
      {
        "firstname": "Camille",
        "lastname": "Richard"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

奖金

以下是我用来为模拟解析器生成随机大小数组的方法:

const randomArray = (min, max, callback) => {
  const size = random.number({min, max});
  return Array.from({length: size}, callback);
};
Enter fullscreen mode Exit fullscreen mode

我们可以像这样使用这种方法重构以前的解析器:

const mockResolvers = {
  Query: () => ({
    persons: () =>
      randomArray(2, 6, () => ({
        firstname: name.firstName(),
        lastname: name.lastName(),
      })),
  }),
};
Enter fullscreen mode Exit fullscreen mode

我创建了一个存储库,其中包含本文介绍的所有资源。欢迎反馈🙏如有任何疑问,请在推特上@YvonnickFrin

鏂囩珷鏉ユ簮锛�https://dev.to/yvonnickfrin/mock-your-graphql-server-realistically-with-faker-js-25oo
PREV
Next.js 13 + RSC 是个好选择吗?我构建了一个没有客户端 JavaScript 的应用来一探究竟
NEXT
✏️ 跟我一起学 ES6:第一部分