Since Facebook released its data querying language back in 2015, it has certainly caught on. GraphQL is very popular in the developer community now and it’s a pleasure to work with. If you’d like to find out more about GraphQL you should watch this documentary.

I am currently using Prisma, GraphQL Yoga and Apollo for one of my hobby projects.

  • Prisma is a GraphQL Database interface that provides you with an intuitive API that exposes plain old JavaScript objects.
  • GraphQL Yoga is an Express GraphQL server that enables you to write Queries and Resolvers in a very neat and tidy way 🧘‍♀️
  • Apollo provides the data graph and help you manage your data – such as performance GraphQL mutations and fetching queries.

I am writing this post because I feel it may help someone understand how Apollo works, essentially. Your schema.graphql file contains the Query, Mutation and other types and determines the shape of the data that is returned:

schema.graphql
type Query {
   user: User // the shape of the User (which will look like a Javascript object)
} 

type Mutation {
   signin(email: String!, password: String!): User! // when you run the signin mutation, you need to pass an email address and a password, and a User will be returned 
}

And in your datamodel.graphql you will have all the ‘Types’ which you have created. This contains your Type names: User, BillingAddress – and inside each has a list of names and primitive data types:

datamodel.graphql
type User {
  id: ID! @id
  email: String! @unique
  password: String!
  resetToken: String
  resetTokenExpiry: String
  company: [Client] @relation(name: "CompanyAssociation", link: INLINE)
  permissions: [Permission]
  first_name: String
  last_name: String
  billing_address: BillingAddress @relation(link: INLINE)
}

type BillingAddress {
  id: ID! @id
  bill_to_name: String
  bill_to_address_1: String
  bill_to_address_2: String
  bill_to_town: String
  bill_to_city: String
  bill_to_postcode: String
}

Now when you run this command prisma-migrate (formerly prisma-deploy), it scans over your datamodel.graphql file and generates another file called prisma.graphql. This is the actual schema file that contains ALL the possible combinations of GraphQL queries and mutations you could think of. It is usually stored in the ‘generated’ directory.

When you write a mutation to Create a User,  you need to code something like this:

CreateUserForm.js
const CREATE_USER_MUTATION = gql`
  mutation CREATE_USER_MUTATION(
    $first_name: String
    $last_name: String
    $billing_address: BillingAddressCreateInput
    $email: String!
    $password: String!
    $repeat_password: String!
    $permissions: [String!]!
  ) {
    createUser(
      first_name: $first_name
      last_name: $last_name
      billing_address: $billing_address
      email: $email
      password: $password
      repeat_password: $repeat_password
      permissions: $permissions
    ) {
      message
    }
  }
`;
As you can see above, I noticed that the $billing_address is itself a Type. So logically in my head this is how I would write the mutation:
schema.graphql
type Mutation {
   createUser(
    email: String!,
    billing_address: BillingAddress
    email: String!
    password: String!
    repeatPassword: String!
    permissions: [String!]!
    password: String!
   ): User!
}

However, this would in fact be incorrect. The way to find out how to find the right type is by searching through the generated prisma.graphql file (which can be found in the generated folder) and looking for the Type Mutation {}. Then start looking for the mutation you’re implementing, which in this case is createUser(). Now the Mutation ‘class’  should like something like this:

prisma.graphql
type Mutation {
  createBillingAddress(data: BillingAddressCreateInput!): BillingAddress!
  updateBillingAddress(data: BillingAddressUpdateInput!, where: BillingAddressWhereUniqueInput!): BillingAddress
  updateManyBillingAddresses(data: BillingAddressUpdateManyMutationInput!, where: BillingAddressWhereInput): BatchPayload!
  upsertBillingAddress(where: BillingAddressWhereUniqueInput!, create: BillingAddressCreateInput!, update: BillingAddressUpdateInput!): BillingAddress!
  deleteBillingAddress(where: BillingAddressWhereUniqueInput!): BillingAddress
  deleteManyBillingAddresses(where: BillingAddressWhereInput): BatchPayload!
  createUser(data: UserCreateInput!): User!
  updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User
  updateManyUsers(data: UserUpdateManyMutationInput!, where: UserWhereInput): BatchPayload!
  upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User!
  deleteUser(where: UserWhereUniqueInput!): User
  deleteManyUsers(where: UserWhereInput): BatchPayload!
}

As you can see above, what has happened is the command prisma generate has done is scanned over our datamodel.graphql file and spat out all the possible Mutations. The one we are going to focus on here is the createUser(). As you can see it provides you with data: UserCreateInput. If we then copy UserCreateInput and search the document, we will eventually come across another object that looks like this:

prisma.graphql
input UserCreateInput {
  id: ID
  email: String!
  password: String!
  resetToken: String
  resetTokenExpiry: String
  company: ClientCreateManyWithoutUsersInput
  permissions: UserCreatepermissionsInput
  first_name: String
  last_name: String
  billing_address: BillingAddressCreateOneInput
  current_password: String
  new_password: String
  repeat_password: String
}

And we finally arrive at the reason why we would not put BillingAddressData, but instead put BillingAddressCreateOneInput. You can now continue to look at the nested objects to see where they lead you. If you search for the BillingAddressCreateOneInput object in the same file, you’ll come to another object or ‘class’ with multiple options for what kind of mutation you would like to perform: create, update, upsert, delete, connect, disconnect, etc.

GraphQL is pretty confusing, but once you learn and can utilise the power of the querying language, you will never go back. You can even integrate GraphQL with WordPress nowadays by using a Framework like Gatsby.js.