如何定义包含复杂对象的 GraphQL 类型模型?

Posted

技术标签:

【中文标题】如何定义包含复杂对象的 GraphQL 类型模型?【英文标题】:How to define a GraphQL type model that contains complex objects? 【发布时间】:2018-06-22 23:30:31 【问题描述】:

我正在使用 Facebook Graph API 的数据来获取用户信息并在 GraphQL 服务 (graphcool) 中创建我的用户。

function createGraphcoolUser(facebookUser) 
    return api.request(`
      mutation 
        createUser(
          facebookUserId: "$facebookUser.id"
          facebookEmail: "$facebookUser.email"
          facebookName: "$facebookUser.name"
          facebookPicture: "$facebookUser.picture"
        ) 
          id
        
      `)
      .then((userMutationResult) => 
        return userMutationResult.createUser.id
      )

$facebookUser.picture 是具有嵌套字段的对象。


  "id": "123467890",
  "email": "my@email.ca",
  "name": "John Doe",
  "picture": 
    "data": 
      "url": "https://url.to.picture.jpg"
    
  

那么如何在类型模型中定义呢?

type User @model 
  # Required system field:
  id: ID! @isUnique # read-only (managed by Graphcool)

  # Optional system fields (remove if not needed):
  createdAt: DateTime! # read-only (managed by Graphcool)
  updatedAt: DateTime! # read-only (managed by Graphcool)

  facebookUserId: String @isUnique
  facebookEmail: String
  facebookName: String
  facebookPicture: ---> HERE <---

  posts: [Post!]! @relation(name: "UserPosts")

【问题讨论】:

你能把图片的URL存储为字符串吗? facebookPicture: "$facebookUser.picture.data.url" 是的,我暂时这样做了……但我想知道如何存储复杂的对象。 您也可以将facebookPicture 字段设置为 JSON 类型以保持结构,但您会失去一些验证能力。 好的,明天检查一下,谢谢 【参考方案1】:

如果您需要 facebookPicture 作为类型,我认为有几种方法可以做到。看来data 对象只是一个包装器,因此它可以帮助我们将整个事物扁平化。

type User @model 
  id: ID! @isUnique

  facebookUserId: String! @isUnique # unique field should be required
  facebookEmail: String
  facebookName: String

  facebookPicture: FacebookPicture @relation(name: "UserPicture")

  posts: [Post!]! @relation(name: "UserPosts")


type FacebookPicture @model 
  id: ID! @isUnique
  user: User! @relation(name: "UserPicture")
  url: String!

在 Graphcool 1.0 之前,它将强制关系成为双向关系,因此您还必须处理图像中的 user 字段。在 1.0 最终推出之后,这可能会变得更简单。

为了将图像添加给用户,您可以(应该能够)使用nested mutation。比如:

mutation createUserAndFacebookPicture  # this mutation should be generated by Graphcool
  createUser(
    # user stuff...
    facebookPicture: 
      url: "$facebookUser.picture.data.url"
    
  ) 
    id
    facebookPicture 
      id
      url
    
  

如果facebookUser.picture.data 更复杂,而不仅仅是包装器,那么您可以创建一个data 字段,并将其设置为JSON 类型。

【讨论】:

【参考方案2】:

为了回答我自己的问题,信息在文档中(对此感到抱歉):

我们必须使用输入类型

...您还可以轻松传递复杂的对象。这尤其 在发生突变的情况下很有价值,您可能希望传入一个 要创建的整个对象。在 GraphQL 模式语言中,输入 类型看起来与常规对象类型完全相同,但具有 关键字输入而不是类型...

http://graphql.org/learn/schema/#input-types

【讨论】:

以上是关于如何定义包含复杂对象的 GraphQL 类型模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 GraphQL 中为对象中的对象列表定义类型

如何在 Graphql 中返回 JSON 对象并定义 JSON 类型

如何使用 type-graphql 定义对象类型

如何在我的GraphQL中为对象中的对象列表定义类型

如何重命名从 Django 模型自动生成的 GraphQL 类型字段?

graphql + mongoose + typescript,如何减少重复的模型定义