嵌套突变有多糟糕?

时间:2016-12-13 12:47:47

标签: graphql

我知道它会被视为反模式,但为什么呢?

mutation {
  createUser(name: "john doe") {
    addToTeam(teamID: "123") {
      name,
      id
    },

    id
  }
}

这不比两个HTTP调用更方便吗?

mutation {
  createUser(name: "john doe") {
    id, # we store the ID
  }
}

mutation {
  addToTeam(userID: id, teamID: "123") {
    name,
    id,
  }
}

2 个答案:

答案 0 :(得分:8)

如果您有//Ingredient.h @interface Ingredient : RLMObject @property (nonatomic, copy, readwrite) NSString *name; @end RLM_ARRAY_TYPE(Ingredient) //Recipe.h @interface Recipe : RLMObject @property (nonatomic, strong, readwrite) RLMArray<Ingredients *>< Ingredients> *ingredients; @end Ingredient *tomato = [[Ingredient alloc] init]; tomato.name = @"tomato"; Ingredient *onion = [[Ingredient alloc] init]; onion = @"onion"; Recipe *recipe = [[Recipe alloc] init]; [realm beginWriteTransaction] [recipe.ingredients add:tomato]; [recipe.ingredients add:onion]; [realm.commitWriteTransaction]; 之间的关系,则可以公开此API:

创建用户,与现有团队相关

Team

创建新用户和新团队

User

这正是Graphcool API处理此问题的方式,如this blog article所示。您可以在the documentation中找到另一个示例。

答案 1 :(得分:1)

这是反模式的原因有两个:

首先,这里有两个原子操作,每个操作可能涉及一些与认证,验证和产生不同错误相关的额外逻辑。因此将它们混合在一起可能会带来一些额外的复杂性。

例如,假设一个团队只能有10个人,并且已达到最大值。撰写操作是否应该完全失败?我们只是添加用户但不将其添加到团队中吗?响应会是什么样的?

第二次,以这种方式集中两个操作可能会暴露应用程序逻辑。人们可能会试图使用这样的突变来执行“当X发生时,Y也应该发生”。例如,在向发票添加新行时,总计应更新。这应该是一个突变, addLineToInvoice ,并且逻辑驻留在服务器上。

在某种程度上,API的命令部分更好地以进程(或操作)为中心,而不是以数据为中心。如果您的API调用专注于数​​据操作,那么您就有可能在客户端加载应该存在于服务器中的业务逻辑。您可能也会失去很多好东西,比如中间件(这对于横切关注点很重要,比如权限和日志记录)。