如何在GraphQL和Apollo中部分模拟架构?

时间:2018-11-14 16:57:14

标签: graphql apollo apollo-server

我正在尝试仅模拟以下Contact类型的一小部分。我的解析器从REST端点返回Contact中除test之外的所有字段的数据。出于演示目的,我希望能够保留所有其他字段的服务器数据,但仅模拟test字段。

我定义了以下GraphQL模式:

const typeDefs = `
    type Contact {
        id: String,
        first_name: String
        last_name: String
        middle_name: String
        date_of_birth: String
        test: String
    }

    type Query {
        contacts: [Contact!]!
        Contact(id: String!): Contact!
    }
`;

我定义了以下模拟:

const mocks = {
    Contact: () => ({
        test: () => "This data is mocked!"
    })
};

并定义了以下解析器:

const resolvers = {
  Query: {
    contacts: async (parent, args, { dataSources }) =>
      dataSources.MYAPI.getAllContacts(),
    Contact: async (parent, { id }, { dataSources }) =>
      dataSources.MYAPI.getContact(id)
  }
};

然后我用以下命令初始化服务器:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  mocks,
  dataSources: () => {
    return {
      MYAPI: new MYAPI()
    };
  },
  mockEntireSchema: false
});

以上操作无效。我添加了mockEntireSchema:true配置,以防止服务器响应被覆盖,但是test属性仍然返回默认的Hello World字符串模拟,而不是我尝试的This data is mocked!模拟。

我知道模拟程序设置正确,因为我可以删除mockEntireSchema配置并正确显示模拟数据。

这是否有可能,或者mockEntireSchema和模拟对象的行为通常不支持这一点?

3 个答案:

答案 0 :(得分:1)

根据documentation,您想将mockEntireSchema保留为false,并创建一个mocks对象,其中包含您仍要模拟的组件。所有其他解析器将按原样使用。但是,将使用您已定义的所有模拟,因此将不会使用返回Contact类型的查询解析器,因为您已将Contact定义为模拟。

答案 1 :(得分:0)

我还没有尝试过,但对我来说似乎应该可以(您所描述的)。但是由于没有,可能的解决方法是只为df['sum']字段添加一个字段解析器:

function rotateStr(a, x, y) {
  return `rotate(${a}, ${x}, ${y})`
  // return 'rotate(' + x + ',' + y + ',' + z + ')' if you can't use templates
}

var x = 20;
var y = 20;
object.children[0].setAttribute('transform', rotateStr(-20, x, y))

答案 2 :(得分:0)

我现在认为这实际上是Apollo https://github.com/apollographql/graphql-tools/issues/1114中的错误。当您使用preserveResolvers: truemockEntireSchema: false(它们是相同的)时,它不会覆盖现有的解析器,但是,我是根据我的模拟配置将那些解析器过滤掉的,因此不会首先加载它们

这使部分模拟原则上起作用。但是,错误是嵌套的() => MockList(100)调用会在graphql程序包中引发错误,因为graphql将MockList object解释为“不可迭代”。 preserveResolvers: false

不会发生这种情况