0

I am using the Facebook Graph API's data to get the user info and create my user in the GraphQL service (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
      })
}

But ${facebookUser.picture} is an object with nested fields.

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

So how do I define it in the type model ?

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")
}
Matt Morgan
  • 4,900
  • 4
  • 21
  • 30
Gab
  • 2,216
  • 4
  • 34
  • 61

2 Answers2

0

If you need the facebookPicture to be a type, I think there's a couple ways to do it. It appears that the data object is just a wrapper, so it could help us to flatten the whole thing down.

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!
}

Prior to Graphcool 1.0, it will force the relationship into being two-way, so you will have to handle having a user field in the image as well. This might become a bit simpler after 1.0 is finally rolled out.

In order to add the image to the user, you can (should be able to) use a nested mutation. Something like:

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

If there the facebookUser.picture.data is more complicated and not just a wrapper, then you could make a data field, and make that a JSON type.

ptpaterson
  • 9,131
  • 4
  • 26
  • 40
0

To answer my own question the info was in the docs (sorry about that):

We must use Input types

... you can also easily pass complex objects. This is particularly valuable in the case of mutations, where you might want to pass in a whole object to be created. In the GraphQL schema language, input types look exactly the same as regular object types, but with the keyword input instead of type ...

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

Gab
  • 2,216
  • 4
  • 34
  • 61