Skip to main content

GraphQL Interfaces

GraphQL supports interfaces similar to other type systems. Interfaces are abstract types that hold a certain set of fields. A type must include these fields to implement the interface.

Interfaces are powerful, and a great way to build and use GraphQL schemas through the use of abstraction. Abstract types can't be used directly in the schema, but can be used as building blocks for creating explicit types.

For example, you could have an interface Car that represents any model of a Car in a trade show:

interface Car {
id: ID!
name: String!
model: String
}

This means that any type that implements Car needs to have these exact fields, with these arguments and return types.

For example, here are some types of brands that might implement Car:

type Audi implements Car {
id: ID!
name: String!
model: String
}
type Bentley implements Car {
id: ID!
name: String!
model: String
}

Now it can be used in another type like this:

type Customer {
owns: [Car!]
}

The owns field uses the Car interface. This allows owns to have values of type Audi and Bently.

IMPORTANT

When creating or updating a customer object, the hypi.impl field MUST be specified on each object in the owns array. Each object of type owns must tell Hypi if it is an Audi or a Bently.

The hypi.impl field is needed for upsert, not for queries. For queries on each implementation, you MUST use an inline fragment i.e.

... on <Impl> { <impl specific fields> }

Here follows the example that inserts data in the Customer object using an interface Car.

mutation Upsert($values: HypiUpsertInputUnion!) {
upsert(values: $values) {
id
}
}

Check the use of inline fragments to retrieve interface data. (... on Audi { model })

{
find(type: Customer, arcql: "*") {
edges {
node {
... on Customer {
owns {
#Retrieve data from interfaces
... on Audi \{ model }
... on Bentley \{ model }
name
}
}
}
cursor
}
}
}

You may use sub-queries on the interface fields. (arcql: "owns.model = 'vx'"). Check the below example.

{  
find(type: Customer, arcql: "*") {
edges {
node {
... on Customer {
owns(arcql: "model = 'vx'") {
#Retrieve data from interfaces
... on Audi \{ model }
... on Bentley \{ model }
name
}
}
}
cursor
}
}
}