# Types

A GraphQL schema is made out of types. This section describes the different set of types and how they can be defined to work with Lighthouse. For a more in-depth reference about types, look into the GraphQL documentation (opens new window)

# Object Type

Object types define the resources of your API and are closely related to Eloquent models. They must have a unique name and have a set of fields.

type User {
  id: ID!
  name: String!
  email: String!
  created_at: String!
  updated_at: String
}

type Query {
  users: [User!]!
  user(id: ID!): User
}

# Scalar

Scalar types are the most basic elements of a GraphQL schema. There are a few built in scalars, such as String or Int.

Lighthouse provides some scalars that work well with Laravel out of the box, you can find them in the default schema.

Define your own scalar types by running php artisan lighthouse:scalar <Scalar name> and including it in your schema. Lighthouse will look for Scalar types in a configurable default namespace.

scalar ZipCode

type User {
  zipCode: ZipCode
}

You can also use third-party scalars, such as those provided by mll-lab/graphql-php-scalars (opens new window). Just composer require your package of choice and add a scalar definition to your schema. Use the @scalar directive to point to any fully qualified class name:

scalar Email @scalar(class: "MLL\\GraphQLScalars\\Email")

Learn how to implement your own scalar. (opens new window)

# Enum

Enums are types with a restricted set of values (similar to enum found in database migrations). They are defined as a list of UPPERCASE string keys. You can define the actual values through the @enum directive.

enum EmploymentStatus {
  INTERN @enum(value: 0)
  EMPLOYEE @enum(value: 1)
  TERMINATED @enum(value: 2)
}

Now we can use the enum as part of our schema.

type Employee {
  id: ID!
  name: String
  status: EmploymentStatus!
}

type Query {
  employees: [Employee!]! @all
}

In this example, the underlying values are actually integers. When the models are retrieved from the database, the mapping is applied and the integers are converted to the defined string keys.

return [
  ['name' => 'Hans', 'status' => 0],
  ['name' => 'Pamela', 'status' => 1],
  ['name' => 'Gerhard', 'status' => 2],
];

Queries now return meaningful names instead of magic numbers.

{
  employees {
    name
    status
  }
}
{
  "data": {
    "employees": [
      { "name": "Hans", "status": "INTERN" },
      { "name": "Pamela", "status": "EMPLOYEE" },
      { "name": "Gerhard", "status": "TERMINATED" }
    ]
  }
}

If the internal value of the enum is the same as the field name, @enum can be omitted:

enum Role {
  ADMIN
}

The PHP internal value of the field ADMIN will be string('ADMIN').

# Input

Input types can be used to describe complex objects for field arguments. Beware that while they look similar to Object Types, they behave differently: The fields of an Input Type are treated similar to arguments.

input CreateUserInput {
  name: String!
  email: String
}

type User {
  id: ID!
  name: String!
  email: String
}

type Mutation {
  createUser(input: CreateUserInput!): User
}

# Interface

The GraphQL interface type is similar to a PHP Interface. It defines a set of common fields that all implementing types must also provide. A common use-case for interfaces with a Laravel project would be polymorphic relationships.

interface Named {
  name: String!
}

Object types can implement that interface, given that they provide all its fields.

type User implements Named {
  id: ID!
  name: String!
}

The following definition would be invalid.

type User implements Named {
  id: ID!
}

Interfaces need a way of determining which concrete Object Type is returned by a particular query. Lighthouse provides a default type resolver that works by calling class_basename($value) on the value returned by the resolver.

You can also provide a custom type resolver. Run php artisan lighthouse:interface <Interface name> to create a custom interface class. It is automatically put in the default namespace where Lighthouse can discover it by itself.

Read more about them in the GraphQL Reference (opens new window) and the docs for graphql-php (opens new window)

# Union

A Union is an abstract type that simply enumerates other Object Types. They are similar to interfaces in that they can return different types, but they can not have fields defined.

union Person = User | Employee

type User {
  id: ID!
}

type Employee {
  employeeId: ID!
}

Just like Interfaces, you need a way to determine the concrete Object Type for a Union, based on the resolved value. If the default type resolver does not work for you, define your own using php artisan lighthouse:union <Union name>. It is automatically put in the default namespace where Lighthouse can discover it by itself.

Read more about them in the GraphQL Reference (opens new window) and the docs for graphql-php (opens new window)