Extending types For Data Modelling in GraphQL
Published: 2022-11-08 18:35:14

GraphQL is very good at helping you compose your data from different data sources, for example, by using [federation](https://stepzen.com/product/federation). Type extensions can be very helpful when you're using GraphQL as a data layer or gateway for all your data. GraphQL type extensions allow you to add or replace fields on types that already exist in your schema. This way, you can better organize your data from different sources.

Let's explore how type extensions help with data modeling in GraphQL.

What are Type Extensions
------------------------

Type extensions help you with data modeling in GraphQL, primarily when you work with different data sources. Or want to modify third-party data types that you cannot change directly.

In the GraphQL specification, you can find multiple definitions of type extensions, where "object extensions" are the most common ones. The section [3.6.3. Object Extensions](http://spec.graphql.org/October2021/#sec-Object-Extensions) describes how you can use the `extend` keyword to add or replace fields to an object type.

An example of extending a type would be to the following:

```
type Person {
  id: String
  name: String
  age: Int
}

extend type Person {
  email: String
}
```

The type `Person` will now have the fields `id`, `name`, `age`, and `email`. When we go back to the earlier statement about data composition when working with multiple data sources, this example would be perfect for a situation where the fields `id`, `name`, and `age` come from one source of data (for example, a database). And `email` comes from another data source, let's say a CRM.

In StepZen, this means that the GraphQL schema would look something like this:

```
type Person {
  id: String
  name: String
  age: Int
}

extend type Person {
  email: String 
    @materializer (query: "getPersonEmail", arguments: [{name: "personId", field: "id"}]
}

type Query {
  getPerson(id: ID!): Person
    @dbquery(
      type: "mysql"
      table: "person"
      configuration: "mysql_config"
    )
  getPersonEmail(personId: ID!): String
    @rest (endpoint: "https://some.crm.com/api/person/$personId/email")
}
```      

The GraphQL schema above will get the fields for the type `Person` from the MySQL database using a `@dbquery` connector. For the extended field `email` it will use `@materializer` to get the data from a CRM system using its REST API.

If the database contained an `email` field, it could also be overwritten when using type extensions, as StepZen will always prefer the extended object types.

GraphQL also supports inheritance, which is often seen as an alternative to type extensions. Inheritance is focused on reusing rather than extending types, as you'll learn in the next section.

Extending types versus inheritance
----------------------------------

There's a difference between type extensions and inheritance. You can use inheritance to compose your data in many programming languages or type systems, and GraphQL is no different.

With inheritance in GraphQL, you can reuse field definitions by using [interfaces](https://stepzen.com/docs/connecting-backends/schemas-with-interfaces), meaning you can assign a set of fields to every type that implements this interface. The implementations of this interface only share the types of the interface.

Suppose you have a company that has both full-time employees and seasonal employees that only work in the winter or summer season.

```
interface Employee {
  id: ID
  name: String
  email: String
}

type FullTimeEmployee implements Employee {
  id: ID
  name: String
  email: String
  monthlyWage: Float
}

type SeasonalEmployee implements Employee {
  id: ID
  name: String
  email: String
  hourlyWage: Float
  season: String
}
```

The interface `Employee` has the fields `id`, `name`, and `email`, which is the data the company stores for every employee for example in a database or CRM. Employees working full-time are paid a monthly wage, while a seasonal employee receives an hourly wage instead. Also, the company stores the season the employee is active in.

As both `FullTimeEmployee` and `SeasonalEmployee` are implementing the interface `Employee`, you have the certainty that the definitions of the fields `id`, `name`, and `email` are the same across all employees.

Conclusion
----------

GraphQL can be used as a data layer or gateway to compose this data when working with multiple data sources. Modeling your data in this setup can be done by using type extensions or, in some cases, by using inheritance. This post described how you could use object extensions to extend a type with fields coming from a different data source and inheritance to reuse field definitions for different ones.

Want to try this out? Head over to the [Getting Started](https://stepzen.com/getting-started) section and start building your GraphQL API. Follow us on [Twitter](https://twitter.com/stepzen_dev) or [join our Discord community](https://discord.gg/9k2VdPn2FR) to ask for help when you run into any issue.