What is an interface?

Some entities are what we call an interface. Like in Java, these interfaces are partially abstract entities that can then be extended. For example, the Contacts entity is an interface, that is then extended by Suppliers and others.
The interface entity has base fields that are inherited by all extending entities. The extending entities then add their own specific fields. For example, Contacts has a label field, therefore all extending entities have a label.

What is a fragment?

Some fields implement an interface type and therefore can implement one of multiple types. These different types can have different sub-fields.
For example, a field implementing the Contacts interface can be either an Employee, a Customer or a Supplier. That field will always use the fields available for Contacts, such as label, but the fields added by implementing entities will vary, such as employee_id, a field only available for employees.
A simple query with such a field will therefore look like this:

query{
  Employees{
    edges{
      node{
        work_for{
          id
        }
      }
    }
  }
}

In this example, the work_for field uses the Contacts entity. Therefore, it has an id field, no matter if the contact in question is a supplier or a customer. However, we also want to fetch the fields specific to each entity type. To do so, we use what we call a fragment. It looks like this:

query{
  Employees{
    edges{
      node{
        work_for{
          label
          ... on customerType{
            customer_id
          }
          ... on supplierType{
            supplier_id
          }
        }
      }
    }
  }
}

Here is a breakdown of what is going on:

  • We ask for the id field, that all work_for results have in common
  • We want more data on these bosses, so we then plug our fragments specific to each type with the form "... on type" with types available being given in the interface's page here.
  • We can now fetch fields that are specific to each type, such as customer_id being specific to Customers.

With our test database, the JSON result looks like this:

{
    "data": {
        "Employees": {
            "edges": {
                "node": [
                    {
                        "work_for": {
                            "label": "Scroodge McDuck",
                            "customer_id": "A0000001"
                        }
                    },
                    {
                        "work_for": {
                            "label": "Mickey Mouse",
                            "supplier_id": "S0000002"
                        }
                    }
                    {
                        "work_for": {
                            "label": "Goofy",
                        }
                    }
                ]
            }
        }
    }
}

You can see that the fragment doesn't appear in the structure of the result (there is no "... on"), but that both results have different fields. The first is a customer and we therefore receive the customer_id field that was requested. The second is a supplier and we therefore a supplier_id.

But there is also a third result with only a label and no additional field. That field is simply an employee. We didn't use any fragment for the employeeType, therefore no additional field was returned. As a test, try replacing the customerType fragment with an employeeType fragment:

query{
  Employees{
    edges{
      node{
        work_for{
          label
          ... on employeeType{
            employee_id
          }
          ... on supplierType{
            supplier_id
          }
        }
      }
    }
  }
}