带有嵌套突变的 Graphql?

Posted

技术标签:

【中文标题】带有嵌套突变的 Graphql?【英文标题】:Graphql with nested mutations? 【发布时间】:2017-07-28 23:39:06 【问题描述】:

如果可能的话,我正在尝试弄清楚如何使用 graphql 突变来改变嵌套对象。例如,我有以下架构:

type Event 
    id: String
    name: String
    description: String
    place: Place


type Place 
    id: String
    name: String
    location: Location


type Location 
    city: String
    country: String
    zip: String


type Query 
    events: [Event]


type Mutation 
    updateEvent(id: String, name: String, description: String): Event


schema 
    query: Query
    mutation: Mutation

如何在我的 updateEvent 突变中添加地点信息?

【问题讨论】:

这可以作为灵感:graph.cool/docs/reference/simple-api/… 【参考方案1】:

如果您想将整个对象添加到突变中,您必须定义类型输入的 graphql 元素。这是一个小cheatsheet的链接。

在您的情况下,它可能如下所示:

    type Location 
        city: String
        country: String
        zip: String
    

    type Place 
        id: String
        name: String
        location: Location
    

    type Event 
        id: String
        name: String
        description: String
        place: Place
    

    input LocationInput 
       city: String
       country: String
       zip: String
    

    input PlaceInput 
        id: ID!
        name: String!
        location: LocationInput!
    

    type Query 
        events: [Event]
    

    type Mutation 
        updateEvent(id: String, name: String, description: String, place: PlaceInput!): Event
    

    schema 
        query: Query
        mutation: Mutation
    

【讨论】:

有什么办法可以避免提供所有的嵌套字段?例如,如果我不提供完整的位置对象,我不提供的字段将被替换为 null 或删除。有什么想法吗? 您可以删除“!”从输入类型,则不再需要。这样做你可以只使用位置对象的一部分。我认为在解析器函数中它将是未定义的。但我不确定。 这应该行不通。 GraphQL.org 表示 The fields on an input object type can themselves refer to input object types, but you can't mix input and output types in your schema. 你需要一个额外的 LocationInput 类型。【参考方案2】:

一般来说,您应该避免将突变的参数视为对架构中对象类型的直接映射。虽然它们确实经常相似,但您最好在假设它们不会相似的情况下处理事情。

以您的基本类型为例。假设我想创建一个新事件,但不知道位置,我只知道经度/纬度 - 它实际上是后端从这些数据中计算出真实的位置对象,我当然不知道它的 ID(它还没有!)。我可能会这样构建我的突变:

input Point 
  longitude: Float!
  latitude: Float!


input PlaceInput 
  name
  coordinates: Point!


type mutation 
  createEvent(
    name: String!
    description: String
    placeId: ID
    newPlace: PlaceInput
  ): Event  
  updateEvent(
    id: ID!
    name: String!
    description: String
    placeId: ID
    newPlace: PlaceInput
  ): Event
)

突变基本上只是一个函数调用,最好按照这些术语来考虑。如果您编写了一个函数来创建一个事件,您可能不会向它提供一个事件并期望它返回一个事件,您应该提供创建事件所需的信息

【讨论】:

我正要问与 OP 相同的问题 - 在这种情况下,createEvent() 的用法会是什么样子,因为 PlaceInput 仍然是一个复杂类型? 您能否也添加一个使用 newPlace 以及它如何访问操作数据的示例解析器函数,示例插入

以上是关于带有嵌套突变的 Graphql?的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套类型的 Graphql 突变?

GraphQL 嵌套突变 + Sequelize

嵌套资源上的 GraphQL 突变

编写嵌套的 GraphQL 突变

graphql 突变不返回嵌套字段

突变中的 GraphQL 嵌套数据