GraphQL Federation based apps
GraphQL has recently been considered as a great alternative to REST APIs. It simply follows the same set of constrains as REST APIs but it organises data into graph using one interface. Its internal properties are represented as nodes and the relationship between nodes is represented by edges in the graphs. Some of the key problems it solves includes:
- Over fetching or under fetching.
- Robust schema definition. Good for documenting API contracts.
- Too many endpoints per API.
- API versioning and others.
In short, GraphQL shines as a query language because it tailor requests for your need i.e it provide exactly what you need.
Developing a GraphQL solution at scale typically requires a different development methodology to allow multiple teams to work on different aspects concurrently. The challenge with the traditional approach is GraphQL should present all data within a single data graph and this rapidly becomes a monolith for enterprise-scale systems. For an enterprise-scale implementation, its often advisable to move from a single-instance/monolithic graphql service to Apollo Federation where rather than having a single graph, we divide graph implementation into multiple sub-graphs (multiple services) where each subgraph has its back-end services, data-store, caching mechanism and can be individually subscribed to.
In other words, we build several GraphQL services independently of one another, then stitch them together into a single GraphQL gateway called the supergraph. This means different team can work simultaneously on each service, have the flexibility to leverage whatever language, database server and caching mechanism they prefer.
Federated GraphQL Architecture
- Allows splitting of a monolith graph while maintaining a single data graph exposed to consumers.
- Industry standard choice for implementing GraphQL in a complex, enterprise environment.
- Allows for separation of concerns facilitating concurrent development by multiple teams allowing scaling out of the solution.
- Faster development cycles. Graphs are built independently as a result, reduces dependency and impediments.
For our project, we chose Apollo Federation for flexibility, horizontal scalability and cohesive user experience across devices and teams. Below is an architecture of how services interoperate.
Fig 1.0 - Proposed MVP Architecture for GQL Federated Instance
Fig 1.1 - Service Interoperation Architecture
A water-down version (for MVP) is attached above. Our API Gateway handles incoming and outgoing traffic, manage authentication, rate-limiting and analytics. Because our Client consumers make HTTP requests to the API proxy rather than directly to our Federated GQL Gateway instance, they dont need to know anything about the implementation of our services or associated subgraphs. They only require the following:
- The URL of the API Proxy endpoint.
- Any headers attached to the Client request.
- Any required authentication and authorisation credentials.
Architecture Component Description
Clients
The Client represent consumers of all kind looking to get some payload from the GraphQL API servers. This ranges from web apps, mobile apps, third party integration and other portable devices.
Client devices are generally internet-connected which allows them to access our API Gateway instance server.
API Gateway Proxy / Load Balancer
Fig 1.2 API Gateway / Load Balancer
API Gateway proxy is a server component that sits between the internet and our Federated Gateway instances. It accepts HTTP requests, provide various services and forward requests to one or many servers.
We decided to leverage API Gateway because of the following:
Load Balancing & Failovers
This is one of the key benefits of using API Gateway as a Proxy instance. Here, the proxy routes incoming HTTP requests to a number of identical servers. i.e GraphQL Federated Server instance as shown above. We will also configured a failovers server as backup and as needed, setting max_fails and fail_timeout values to get the backup instances to kick-in.
Security
A proxy can hide the characteristics of our Federated server instances by removing the need for direct internet access to them. Usually, proxy server are placed in an internet facing DMZ whilst the actual Federated instances are inside non-public subnet.
Additional setup can prevent the proxy from brute-force attack by scanning the logs on the proxy server and identifying repeated fail login attempts from a specific IP address and block the address responsible.
Authentication
When using an Identity Provider like Okta, it means users role and factorTypes can be validated once and for all via the proxy. Authentication can take place once, with a token generated, this can be passed to all Federated instances.
SSL Termination
The API Gateway proxy handle incoming HTTPS requests, so it handles encryption and decryption. This means we have a single point of configuration and management for SSL/TLS. It also removes the overhead of having our Federated instances encrypt and decrypt HTTPS traffic.
UI Component Library
MUI, Storybook and Atomic Design
Sample
query 1
query{
customersDetail{
nameDetails{
lastName
firstName
}
}
}
HTTP Headers:
{
"authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJwYXJ0eUlkIjoiMDEyMzQ1Njc4OSJ9.b7fXhoC8s1AvkRN1wghsWRonIXTcAHBSsjV6Wj6IJKs",
"user": "{\"partyId\": \"ba63c64b-254e-45fc-ac16-fc0d9118f30c\"}",
"x-party-id": "ba63c64b-254e-45fc-ac16-fc0d9118f30c"
}
query2
query{
timeAtCustomers
}