import highlight from '@mdx-deck/themes/syntax-highlighter-prism' import { Invert, Split, SplitRight, FullScreenCode, Horizontal } from 'mdx-deck' import { Appear, Head, Notes } from 'mdx-deck' import { summit } from './theme.js'
export const themes = [ highlight, summit ]
- 20+ years
- Corporate IT, SQL DBA, Microsoft
- Web, React Native
- Patterns, SOLID, Architecture
- I like things that work
@jhampton (twitter, github)
Hello everyone, I'm Jeff Hampton. I recently joined Apollo as a solutions architect. My career winds through corporate IT where I slept with a BlackBerry strapped to my underwear, through PHP4 and various web tech, and finally more native-focused tech and working on patterns and architecture.I like things that work. I don't have a personal brand. You can occasionally find me on Twitter, but more regularly on GitHub.
- Sparked conversations, wide adoption
- Language Support (show graphics)
- Java, JS/ TS, Ruby, Python, .NET
- Why Federation?
- What does is solve?
- Entities, Value Types, and Services
- Syntax and Reasoning
- Ecommerce Demo
- Build the services
First let's walk through the challenges that Federation addresses. Next we'll look at how Federation is implemented, and then quickly move into building a Federated graph. Our demo will be an ecommerce graph that has products, reviews, and accounts. We're going to separate the graph by concern into individual services and extend those services, seeing how that affects
Framing the problem
Decoupling, no more monoliths at scale
What about stitching?
Implementation in parts, separate concerns
We heard this from teams, not confident they could scale
Once teams see the power of GraphQL is that it's awesome. As teams place more into graph, hard to scale.
The power of monoliths...TK
Previously, the solution was schema stitching. It allows for multiple services to be composed into a single graph. TK Provide more color around
Apollo heard a consistent message from our community: GraphQL at scale can become a monolith.
While stitching addresses some of the problem, it's a leaky abstraction, placing logic into the gateway.
Like the underlying services, implementation should be in parts. You should separate concerns on organizational or technical lines. Maybe you have alower-moving portions of your schema, or geographically-distributed teams that want to move quickly.
We heard about these kinds of challeneges, but perhaps you're wondering...
Do you ...
- Do you have separate GraphQL services today?
- Do you want modular portions of your graph?
- Do features have different security requirements?
- Do features have different performance requirements?
- Do you have different deployment cadences?
Is this just hype
Adoption is simple and follows same basic rules defined in the Federation specification. Your current server likely has support, and investing today decreases risk during scaling events.
POLL THE AUDIENCE - Get them involved
- Modularity
- Separate GraphQL Services today?
- KEEP YOUR HANDS RAISED
So these are some of the questions you might think about when approaching a federated graph. We believe there is immediate value and a greater chance of long-term success in adopting federation TODAY.
Federation is for you. We want something we can adopt incrementally...
- Adoption is incremental
- Implementation is simple
- Wide support
- Provides a clear path to scale
Listened to the needs of our customers...
We talked to all these people...
We strive to deliver the most thoughtful and useful tools, so we took the myriad conversations from our community, TK
We took what we heard... TK
"Instead of implementing an organization's entire data graph layer in a single codebase, responsibility for defining and implementing the graph should be divided across multiple teams. Each team should be responsible for maintaining the portion of the schema that exposes their data and services, while having the flexibility to develop independently and operate on their own release cycle."
from PrincipledGraphql.com by Matt DeBergalis and Geoff Schmidt
In "Principled GraphQL", Matt and Geoff describe a disciplined approach to GraphQL implementation: a single graph whose pieces can implemented independently.
from "Apollo Federation" by James Baxley III
- GraphQL Syntax
- Static composition & validation
- Supported today
- Benefit from ahead-of-time validation, composition, analysis
Separates:
- Teams' responsibilities
- Logic in Services, not the Gateway
- Code organization vs infra
- Uses SDL primitives
- Opaque to consumers
- Implementation language-agnostic
To a consumer, this is a single graph. Spec-compliant. Transparent rollout, no client changes.
A declarative model for Graph composition of
loosely coupled downstream GraphQL services that enables
static composition and validation of a unified graph, using
query plans to resolve downstream operations.
Core building blocks of Federation
Ecommerce schema
Accounts Service
Reviews Service
Products Service
Books Service
For the rest of the talk, we're going to use a schema for a fictional ecommerce company that defines some basic entities across several services. Now, let's walk through what we need to make Federation work for US.Talk about the services TK
- Reference - type defined in another service
- Extend - query, types
- The ability to reference types across services and
- The ability to add richness to types across services
"In the Accounts service, the base User"
type User @key(fields: "id") {
id: ID!
name: String
username: String
}
We need the ability to reference a given type, defined in one service, from another service. To those familiar with database design, this should look vaguely familiar. We use the Key directive to indicate how we will reference this type across services. Using this directive, we have promoted a simple "value type" into an entity.
It's worth noting that in federation today, only ONE service may define an entity that can be extended by other services.
Now that we have a way to reference an entity, we need a way to enrich that entity from another service: we need to EXTEND.
TK We need to add reviews...
TK Remove references to the query planner
"In Reviews service, add reviews to User entity"
extend type User @key(fields: "id") {
id: ID! @external
username: String @external
"A list of all reviews by the user"
reviews: [Review]
}
We use the extend keyword to indicate that we are extending a previously-defined entity
We match the key signature so that the type is consistent and validates correctly
And now we mark a couple of fields as "EXTERNAL", which means that these fields are provided in the defining service for this entity.
They're not resolved here. The query planner will be able to find those fields on the defined entity service.
Whew. Okay, we're extending this thing, so what did we add? This is the Reviews service, so we added Reviews to the User. Now, our consumers can quickly discover and use Reviews from the User entity. From their perspective, it's a single graph.
Let's build a Federated graph
"""
The base User
"""
type User @key(fields: "id") {
"A globally unique id for the user"
id: ID!
"The users full name as provided"
name: String
"The account username of the user"
username: String
}
View the result in PlayGround
- Playground
- Show query plan (ID is used to fetch that entity!)
- Extend, Push
- New Query
- Show query plan
- Add provides
- Execute queries
- Show AGM
// Reviews service
type Review @key(fields: "id") {
id: ID!
body: String
author: User @provides(fields: "username")
product: Product
}
extend type User @key(fields: "id") {
id: ID! @external
# Let's change the username!
username: Boolean @external
reviews: [Review]
}
- Multiple Keys
- Compound Keys
Demo beats
- Simple
- Show that we can use the individual service! It's "Just GraphQL"
- Show Account Service
- Showing the Review Service
- CONNECT THEM
- Show the query plan
- What about connecting to a public API?
- Show the query plan