How to aggregate and share data with third parties using GraphOS
Shane Myrick
This post is a part of our “How to power modern retail apps with Apollo GraphOS” series. Also in this series:
- Unify your e-commerce checkout with GraphQL
- Personalizing the e-commerce shopping experience with GraphQL
- Creating an omnichannel shopping experience with GraphQL
- Manage time-gated product launches with GraphQL
One of the great things about GraphQL is that it allows you to consolidate data across multiple data sources and present all of that data in a unified view to client developers. For example, in a supergraph for a retail business that might mean fetching product attribute data from an internal source while fetching related review data from a third party service.
Apollo Federation makes this easy—even when different teams need to manage portions of the supergraph schema that provide the product and reviews data in two different subgraphs. Let’s take a look at how that would work.
Linking third-party reviews to products
Imagine that we have a products subgraph that contains the following type definition for Product
:
# Products subgraph
"""
A specific product sold by our store. This contains all the high level details but is not the purchasable item.
See Variant for more info.
"""
type Product @key(fields: "id") @key(fields: "upc") {
id: ID!
title: String
description: String
mediaUrl: String
upc: ID!
"""
Variants of the products to view specific size/color/price options
"""
variants(searchInput: VariantSearchInput): [Variant]
}
We need to add a reviews
field to the Product
type, but the reviews data is managed by another team via a third-party service. To accommodate this, that team can create a new reviews subgraph and add the following definition:
# Review subgraph
type Review {
id: ID!
"The plain text version of the review"
body: String
"The person who authored the review"
author: String
"The product which this review is about"
product: Product
}
The reviews subgraph won’t need to know anything about products except the UPC of the product that the review is associated with (this is one of the key fields that has been identified for the Product
type). For brevity, we’ll assume that it’s possible to configure this value in the third-party reviews service and we’ll also assume this value can be retrieved from that service’s API when querying review data.
The team that owns the new reviews subgraph will then need to write resolvers for this new portion of the schema, including a resolver for the product
field that returns the product ID value so that Apollo Router can forward these values to the products subgraph to be fully resolved with all product details:
const resolvers = {
Review: {
Product: (parent) => parent.product.upc
}
};
We can also make the relationship between products and reviews bidirectional. To associate a list of reviews with a product, we can extend the `Product` entity type from within the reviews subgraph as follows:
type Product @key(fields: "id") @key(fields: "upc") {
id: ID!
reviews: [Review]
}
The reviews subgraph will then need to include a resolver that fetches a list of reviews based on a product’s UPC:
const resolvers = {
Product: {
reviews: (parent) => getReviewsByProductUpc(parent.product.upc)
}
};
Once the reviews subgraph is composed into the supergraph, a client developer will now be able to all product and reviews data seamlessly and as though it all originated from the same data source.
Sharing (some) data back with third parties
Consolidating data across multiple sources is a big win that can help speed up development times for internal teams that build online shopping apps for web and mobile devices, but what about external partners such as third-party sellers that also need access to product data to build their own client apps?
There would likely be some data in supergraph meant for internal use only, such as sensitive user data. So that could mean maintaining two different versions of the supergraph schema to hide this data from external partners, which would require significant development overhead.
Luckily, GraphOS allows you to have the best of both worlds and maintain a single, unified supergraph schema that exposes different views to different API consumers using a feature of Apollo Studio called Contracts (currently available for Enterprise plans).
If we wanted to expose a limited partner schema that only revealed product information to partners, then we can use the special @tag
directive to decorate the Product
type:
type Product @key(fields: "id") @key(fields: "upc") @tag(name: "partner") {
id: ID! @tag(“internal”)
title: String
description: String
mediaUrl: String
upc: ID!
"""
Variants of the products to view specific size/color/price options
"""
variants(searchInput: VariantSearchInput): [Variant]
}
All Product
fields will inherit the partner
tag set on the parent type definition. Keep in mind that this also applies to field extensions from other subgraphs (such as the reviews
field that the reviews subgraph adds to Product
) so you will want to apply tags at the object type level with care, or alternatively, apply them at the field level only for finer-grained control.
We also explicitly set an internal
tag for the product ID field because this value will be used for internal purposes only. Next, we can apply the same partner tag to some product Query
fields:
type Query {
"""
Get all available products to shop for. Optionally provide some search filters
"""
searchProducts(searchInput: ProductSearchInput! = {}): [Product] @tag(name: "partner")
"""
Get a specific product by id. Useful for the product details page or checkout page
"""
product(id: ID!): Product @tag(name: "partner")
}
Now we can create a Contract variant in Apollo Studio that includes the partner
tag and excludes the internal
tag. And with a Contract variant available in Apollo Studio, we can now configure an Apollo Router to serve this supergraph schema only at an endpoint available for third-party partners to query.
Get started with a retail supergraph today
Beyond onboarding third-party partners to supergraph, the best way to see the possibilities of a supergraph is to try one out. You can explore a retail supergraph schema and run real queries against it here.
We also have additional posts in this series of retail best practices that dive into different elements of this schema to illustrate how Apollo GraphOS help power essential features of modern retail applications.
If you’d like to talk to an Apollo expert about how a supergraph can power your retail experience, please reach out to us.