This document summarizes a presentation about graph-quilt, an open source GraphQL orchestrator library. It discusses the challenges of building a GraphQL orchestrator to unify data from multiple services. Graph-quilt addresses this by allowing services to register their GraphQL schemas and composing them into a unified schema. It also supports features like remote schema extensions, authorization, and adapting existing REST APIs. The presenters believe graph-quilt provides a flexible way to build GraphQL gateways and help more clients adopt GraphQL.
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak Shaikh & Lucy Shen
1. Weaving Microservices
into a Unified GraphQL
Schema with graph-quilt
Ashpak Shaikh | Sr Staff Software Engineer
@shaikh__ashpak
Lucy Shen | Developer Advocate
@spooleans
2. Ashpak Shaikh
Sr Staff Software Engineer, Intuit
- Tech Lead/Architect - Dynamic Experience Platform
- Intuit API Steward
- GraphQL Expert
- Passion for service orchestration and Domain
Specific Languages (DSLs)
@shaikh__ashpak
in/ashpak--shaikh
3. Lucy Shen
Developer Advocate, Intuit
Former frontend software engineer (and JavaScript
apologist) turned Developer Advocate. My work is
focused on developer education and community building
in Intuit’s open source and API strategy. And I do a lot of
cosplay & photography in my free time!
@spooleans
in/lucyjshen
4. • GraphQL 101
• Quick graph-quilt demo
• GraphQL orchestrator history & architecture
• Schema composition using graph-quilt (and other features!)
On the agenda:
5. Intuit is the global
financial technology
platform that powers
prosperity for more than
100 million customers
worldwide.
8. • A query language API (not a database
technology)
• Services can be written in any language
• Open-sourced by Facebook in 2015
What is GraphQL?
Sample query
Sample response
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
9. • As the name suggests, it’s the language
used to define your schema 😂
• Your schema describes the shape of your
available data to the GraphQL server
• It also defines queries and mutations
available to the client
Schema Definition Language (SDL)
Sample schema
type Character {
name: String!
appearsIn: [Episode!]!
}
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
}
10. STEP 1
Create a Schema
(SDL - Schema Definition Language)
type Query {
petById(id: ID!): Pet
}
type Pet {
id: ID!
name: String!
status: Status!
}
STEP 2
Implement DataFetchers (Resolvers)
(DGS Guide)
@DgsComponent
public class PetDataFetcher {
@Autowired
PetStoreDao petStoreDao;
@DgsQuery
public Pet petById(@InputArgument String id) {
return petStoreDao.findById(id);
}
}
Creating a GraphQL Service
20. Let’s create our own GraphQL Orchestrator
● Senior Leadership and Architect
community approved a mission
team in 2018.
● Modest Goal : Tax + Credit
Service
● Vision : Single endpoint Data API
21. First Principles
Execution
● GraphQL specification for
schema authoring and subgraph
communication.
Registration
● Loose coupling between
orchestrator and subgraph.
27. Schema composition
● Number of subgraphs grew organically.
● Schema organization requests came in.
● Dependency between the subgraphs started emerging.
● Clients are spoilt and always want to make a single query.
● Diverse literature and spec for distributed GraphQL schemas.
28. Recursive Merge
User subgraph Tax subgraph Unified Schema
type Query {
user(id: ID!): User
}
type User {
personalInfo: PersonalInfo
}
type PersonalInfo {
id: ID!
firstname: String
lastname: String
email: EmailAddress
}
scalar EmailAddress
type Query {
user(id: ID!): User
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int): TaxInfo!
}
type TaxInfo {
…
}
type Query {
user(id: ID!): User
}
type User {
personalInfo:PersonalInfo
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int): TaxInfo!
credit: CreditInfo!
}
type PersonalInfo { … }
type TaxInfo { … }
type CreditInfo { … }
scalar EmailAddress
query QUERY_USER {
user(id:”myId”) {
personalInfo { … }
finance {
tax { … }
credit { … }
}
}
}
type Query {
user(id: ID!): User
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
credit: CreditInfo!
}
type CreditInfo {
…
}
Credit subgraph
29. Remote Type Extension - @resolver
Tax subgraph
type Query {
user(id: ID!): User
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int!): [TaxInfo]
}
type TaxInfo {
taxId: ID!
year: Int!
…
}
Unified Schema
type Query {
user(id: ID!): User
taxDocument(id: ID!,
year: Int!): TaxDocument
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int!): [TaxInfo]
}
type TaxInfo {
userId: ID!
year: Int!
…
taxDocument: TaxDocument
}
…
query QUERY_USER {
user(id: “123”) {
finance {
tax(year: “2022”) {
taxDocumment {
…
}
}
}
}
}
type Query {
taxDocument(id: ID!,year: Int!):
TaxDocument
}
type TaxDocument {
year: Int
forms: [TaxForm]
}
type TaxForm { … }
Tax Documents subgraph
Field Reference
extend type TaxInfo {
taxDocument: TaxDocument @resolver(
field: "taxDocument"
arguments: [
{name: "id", value: "$taxId"},
{name: "year", value: "$year"},
]
)
}
# local type reference
type TaxDocument {}
30. Remote Type Extension - Apollo Federation
Tax subgraph
type Query {
user(id: ID!): User
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int!): TaxInfo!
}
type TaxInfo @key(fields: "taxId year") {
taxId: ID!
year: Int!
…
}
Unified Schema
type Query {
user(id: ID!): User
}
type User {
finance: FinanceInfo
}
type FinanceInfo {
tax(year: Int!): TaxInfo!
}
type TaxInfo {
taxId: ID!
year: Int!
…
taxDocument: TaxDocument
}
…
query QUERY_USER {
user(id: “123”) {
finance {
tax(year: “2022”) {
taxDocumment {
…
}
}
}
}
}
type TaxInfo @extends @key(fields:
"taxId year") {
taxId: ID! @external
year: Int! @external
taxDocument:TaxDocument
}
type TaxDocument {
year: Int
forms: [TaxForm]
}
type TaxForm { … }
Tax Documents subgraph
32. GraphQL Authorization
● Restrict access to the supergraph
○ Real user vs System user
○ Session with a lower access level
○ User consented data access
○ Intuit vs Third party apps
● Authz solutions for REST APIs are not applicable.
● Central Authz Enforcement.
34. REST Adapter (graphql-service-adapters)
Problem
● Clients love GraphQL and now need data from
REST APIs.
● REST services not be ready to adopt GraphQL.
Solution
● The orchestrator projects the data from REST
endpoint to match the GraphQL Schema.
● REST adapter pipeline with validation.