Leveraging Interfaces in GraphQL Schema Design
By: Ryan Kanner @CodeProKid
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099492/white.png)
©2020 Copyright - Confidential and Proprietary
About Me
-
Live in Denver, CO
-
Engineer on the Content Platform / WordPress team @ NerdWallet
-
Co-organizer of GraphQL & WordPress meetups in Denver
-
Help maintain WPGraphQL, an open source project bringing GraphQL to WordPress
-
Crazy dog, Blake
-
Baseball Fan
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7107597/13305263_10156918785205147_1236427800882803115_o.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7107599/IMG_20170408_190149.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7107767/IMG_20190901_141343.jpg)
... I also love Pizza
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7100879/amirali-mirhashemian-w1iMfs6yxuo-unsplash.jpg)
In another lifetime
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7101105/ryan_1_800.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7101114/transparent-mustache-2.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7101122/chef-hat-transparent-2.png)
Killing the Pizza Game
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7107529/car-animated-face.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7107554/money-fan.gif)
![](https://media.giphy.com/media/l2YOCPoZKWumSXo5y/giphy.gif)
A Perfect Combination
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7101078/pizzaql.png)
+
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7101098/kindpng_35083.png)
=
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105988/Buffalo_Chicken.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105991/sausage-olive.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105992/pepperoni.jpg)
Specials Board
query {
specials: [Pizza]
}
type Pizza {
id: ID!
image: String
name: String!
sauce: String
cheese: String
toppings: [String]
price: Float!
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105991/sausage-olive.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105992/pepperoni.jpg)
Updated Specials Board
type Pizza {
id: ID!
image: String
name: String!
sauce: String
cheese: String
toppings: [String]
price: Float!
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106080/garlic-knots.jpg)
type Side {
id: ID!
image: String
name: String!
sauce: String
cheese: String
quantity: Int
price: Float!
}
interface FoodItem {
id: ID!
image: String
name: String!
sauce: String
cheese: String
price: Float!
}
query {
specials: [FoodItem!]
}
So, What are Interfaces?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://media.giphy.com/media/DrRb3w81xxFD2/giphy.gif)
An Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface
interface FoodItem {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
type Pizza implements FoodItem {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
toppings: [String!]
}
type Side implements FoodItem {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
quantity: Int
}
Querying Interfaces
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
query FEATURED_ITEMS {
specials {
__typename
id
name
image
price
sauce
cheese
... on Pizza {
toppings
}
... on Side {
quantity
}
}
}
type Query {
specials: [FoodItem!]
}
interface FoodItem {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
}
type Pizza implements FoodItem {
...
toppings: [String]
}
type Side implements FoodItem {
...
quantity: Int
}
What about unions?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
type Query {
specials: [FoodItem!]
}
union FoodItem = Pizza | Side
type Pizza {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
crust: String
}
type Side {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
quantity: Int
}
query FOOD_ITEM_UNION {
specials {
__typename
... on Pizza {
id
name
price
image
sauce
cheese
crust
}
... on Side {
id
name
price
image
sauce
cheese
quantity
}
}
}
The difference visualized
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
FoodItem
- id
- name
- price
- image
- sauce
- cheese
Pizza
- toppings
Side
- quantity
FoodItem
Pizza
- id
- name
- price
- image
- sauce
- cheese
- toppings
Side
- id
- name
- price
- image
- sauce
- cheese
- quantity
Interfaces
Unions
What about something a little more complex?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://media.giphy.com/media/aCKMaeduKfFXG/giphy.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
Another change to the specials
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105988/Buffalo_Chicken.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106204/garlic-knots.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106205/t-shirt.jpg)
type Pizza {
id: ID!
image: String
name: String!
price: Float!
sauce: String
cheese: String
toppings: [String]
}
type Side {
id: ID!
image: String
name: String!
price: Float!
sauce: String
cheese: String
quantity: Int
}
type Apparel {
id: ID!
image: String
name: String!
price: Float!
inStock: Boolean!
description: String
}
Multiple Interfaces
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
interface FoodItem {
sauce: String
cheese: String
}
type Apparel implements
Product {
id: ID!
name: String!
price: Float!
image: String
inStock: Boolean!
description: String
}
interface Product {
id: ID!
name: String!
price: Float!
image: String
}
type Pizza implements
FoodItem & Product {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
toppings: [String]
}
type Side implements
FoodItem & Product {
id: ID!
name: String!
price: Float!
image: String
sauce: String
cheese: String
quantity: Int
}
Multiple Interfaces Query
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
type Query {
specials: [Product!]
}
query FEATURED_ITEMS {
specials {
__typename
id
name
image
price
... on FoodItem {
sauce
cheese
}
... on Pizza {
toppings
}
... on Side {
quantity
}
... on Apparel {
inStock
description
}
}
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106223/t-shirt.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105988/Buffalo_Chicken.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106231/garlic-knots.jpg)
Pizza
Apparel
Side
Component Mappings
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106223/t-shirt.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106204/garlic-knots.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105992/pepperoni.jpg)
<ProductCard>
fragment pf on Product {
__typename
id
name
price
image
... foodFields
... apparelFields
}
<FoodItemDetails>
fragment foodFields
on FoodItem {
__typename
sauce
cheese
... on Pizza {
toppings
}
... on Side {
quantity
dippingSauce: sauce
}
}
<ApparelDetails>
fragment apparelFields
on Apparel {
inStock
description
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
Multiple DataType Handling Without GraphQL
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7105988/Buffalo_Chicken.jpg)
Pizza
GET /api/v99/pizza/1
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106223/t-shirt.jpg)
Apparel
GET /api/v99/apparel/2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7106231/garlic-knots.jpg)
Side
GET /api/v99/side/3
Takeaways
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
- Interfaces help bring your Type's together, and make your Graph more flexible.
- Make your components more re-usable.
- Using multiple interfaces with Types can unlock powerful Query combinations.
- A tradeoff of using interfaces is that you have to code defensively on the client.
- PizzaQL 4 Life.
Thanks for coming! Questions?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7099506/color.png)
©2020 Copyright - Confidential and Proprietary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/335775/images/7103637/nw-logo.png)
Leveraging Interfaces in GraphQL Schema Design
By Ryan Kanner
Leveraging Interfaces in GraphQL Schema Design
- 1,107