📙 The architect's guide to building scalable global applications |
Learn more
Fauna logo
Product
Solutions
Pricing
Resources
Company
Log InContact usStart for free
Fauna logo
Pricing
Customers
Log InContact usStart for free
© 2023 Fauna, Inc. All Rights Reserved.

Related posts

Building an edge serverless GraphQL backend with Cloudflare Workers and FaunaHow to use Fauna with GraphQL and PHPAccelerating delivery with GraphQL and Fauna

Start for free

Sign up and claim your forever-free Fauna account
Sign up and get started

Request demo

Connect with a Fauna expert
request demo

Table of Contents

Apollo - Fauna Cover Photo

Building scalable solutions with Apollo Federation and Fauna

Shadid Haque|Aug 23rd, 2022|

Categories:

GraphQL
This article explains how you can reduce complexity, develop features faster, and make your engineering teams more efficient using Apollo Federation and Fauna.
Please be advised that Fauna GraphQL currently does not support the subgraph specification of Apollo Federation 2.0.
If you are looking to integrate all the Federation subgraph specs we recommend you use Fauna with a Subgraph Compatible App server. As Fauna is a general purpose database you can use it with any backend server or serverless functions to implement Federation.
Apollo Federation is designed for implementing GraphQL in a microservice architecture. On the other hand, Fauna is a distributed serverless document-relational database delivered as an API. Fauna's native GraphQL API allows engineers to directly integrate it as a subgraph in Apollo Federation or use it as a database for individual microservices.
Apollo Federation combined with Fauna improves developer experience and increases productivity, solving the problem of schema stitching and addressing pain points such as coordination, separation of concerns, and brittle gateway code.

Challenges of modern application development and how to solve it

Many organizations find it challenging to deliver products and features with velocity. More and more organizations are investing massive amounts of resources to make their infrastructure resilient and flexible. Yet, scattered microservices, versioned REST endpoints, and complex database management systems result in slow delivery of features/product development.
GraphQL revolutionized the way organizations build applications. GraphQL, open-sourced by Facebook in 2015, helps engineering teams integrate their array of REST APIs and microservices into a unified schema that frontend developers can query, fetching only the data required to power an experience while being agnostic to the data source. Traditional REST APIs lead to under or over-fetching data.
Fast forward to 2022, and the complexity of modern APIs and applications has grown exponentially. Running everything through a single GraphQL server (read: monolith) with multiple teams rapidly contributing changes creates a bottleneck.
What if there was a way for each microservice to have its own graph that could be seamlessly composed into a supergraph? Enter Apollo Federation. With Apollo Federation, you can build a declarative, modular GraphQL architecture.
A supergraph is composed of smaller graphs called subgraphs, each with its own schema. Teams can evolve their subgraphs independently, and their changes will be automatically rolled into the overall supergraph, allowing them to deliver autonomously and incrementally.
Your application data layer (database) is a critical part of your application architecture. Fauna is a database designed with modern applications and GraphQL architecture in mind. Fauna can seamlessly integrate as a subgraph in your Apollo Federation supergraph.
Moreover, Fauna's custom GraphQL resolvers gives the engineers the ability to turn the database into a fully-fledged microservice. You can learn more about Fauna's GraphQL capabilities in the official docs.
Fauna is a database that gives you the ability to form your data from a declarative GraphQL schema while giving you the complete freedom to implement your resolver functions if you have to. The document-relation model of Fauna also makes it flexible for evolving applications. Fauna combines the simplicity of NoSQL, without sacrificing the ability to model complex relationships.
Fauna’s flexibility and GraphQL native API combined with Apollo Federation allows engineers to build robust solutions faster with more flexibility and less code.
Let’s walk through a few different approaches for how to integrate Apollo Federation and Fauna, depending on your needs and existing architecture.

Application architecture

Microservices and Fauna (Traditional subgraphs)

Having a separate database for each of your microservices is a common practice. You can use the Fauna database as your data layer in each microservices. Your services can connect to Fauna with any of the supported drivers.
This is a traditional microservice-based architecture
This is a traditional microservice-based architecture. Each microservice is a subgraph in this case, and you compose these subgraphs into a supergraph using Apollo Federation.

Using Fauna-hosted GraphQL endpoints as subgraphs

Suppose your product is primarily frontend focused (Jamstack or serverless-native) and you are not ready to commit to multiple microservices yet but want separation of concerns in the data layer. In that case, this architecture pattern is for you.
Using Fauna-hosted GraphQL endpoints as subgraphs
In this pattern, you will ideally have three Fauna databases. Each database has its GraphQL schema. Each of these schemas is then combined into a Federation supergraph.

Hybrid model

In the hybrid model, you combine the two approaches discussed earlier. This is ideal when you are rapidly scaling your product and solutions.
Hybrid model

Getting started with Fauna and Apollo Federation 2

Let’s create a federated e-commerce solution using Apollo Federation and Fauna. In this example app, we will combine a Fauna GraphQL subgraph that includes information about shops and products with one from Apollo that provides locations.
You can find the complete code in this repository.

Configure Fauna

Head over to dashboard.fauna.com and create a new database. Create a new GraphQL schema. You can use the following schema.
type Shop {
  name: String!
  description: String!
  coverImg: String!
  products: [Product]! @relation
  ownerID: String!
}

type Product {
  name: String!
  description: String!
  price: Float!
  category: String!
  imageUrl: String
  shop: Shop! @relation
}

type Query {
  products: [Product]
}
Upload the schema to your Fauna database. Select the GraphQL option in your Fauna dashboard then select import schema.
Upload the schema to your Fauna database
Once you upload the schema your collections in your database will be generated.

Add Records to Your Collection

Next, create some records in Fauna using the GraphQL playground. Run the following mutation to create a new product.
mutation CreateProduct {
  createProduct(
   data: {
    name: "fender stratocaster",
    description: "The world's greatest electric guitar",
    price: 1255,
    imageUrl: "guitar.png",
    category: "Music",
  }
 ) {
   _id
   name
 }
}
Next, create a Shop by running the following mutation.
mutation CreateShop {
  createShop(
   data: {
    ownerID: "1223302094",
    name: "Scarborough Music and Records",
    description: "some music shop",
    coverImg: "example-shop.png"
   }
  ) { _id }
}

Integrate Fauna and Apollo

To integrate Fauna as a subgraph with Apollo Federation, you need the full GraphQL SDL from Fauna. You can download this from the Fauna GraphQL playground. Select schema from the playground and download the schema.
Integrate Fauna and Apollo 1
Integrate Fauna and Apollo 2
Next, navigate to security section and generate a new server key for your database.
New server key
Save new server key

Setting up supergraph

Create a new supergraph-config.yaml file. This file will contain the supergraph specification as well as subgraphs url and schema. Add the following code to your supergraph-config.yaml file.
federation_version: 2
subgraphs:
  fauna:
   routing_url: https://graphql.fauna.com/graphql`
   schema:
     file: ./fauna.graphql
 locations:
   routing_url: https://flyby-locations-sub.herokuapp.com/
   schema:
     subgraph_url: https://flyby-locations-sub.herokuapp.com/
Here, we are federating two subgraphs — one being Fauna and the other is a sample microservice from Apollo.
Run the following command to generate the supergraph
$ rover supergraph compose --config ./supergraph-config.yaml > supergraph.graphql
The previous command composes a supergraph schema from the specified subgraphs. The supergraph schema is saved in the supegraph.graphql file.

Local composition service with Apollo Gateway and Federation

Next, you create a local composition service. Create a new file called index.js and add the following code. This service acts as the gateway to your supergraph.
const { ApolloServer } = require('apollo-server');
const { ApolloGateway, RemoteGraphQLDataSource } = require('@apollo/gateway');
const { readFileSync } = require('fs');

const supergraphSdl = readFileSync('./supergraph.graphql').toString();

class AuthenticatedDataSource extends RemoteGraphQLDataSource {
  willSendRequest({ request, context }) {
    request.http.headers.set('Authorization', context.token);
  }
}

const gateway = new ApolloGateway({
  supergraphSdl,
  buildService({ name, url }) {
    return new AuthenticatedDataSource({ url });
  },
});

const server = new ApolloServer({
  gateway,
  subscriptions: false,
  context: ({ req }) => {
    const token = req.headers.authorization || '';
    return { token };
  },
});

server.listen().then(({ url }) => {
  console.log(`🚀 Gateway ready at ${url}`);
}).catch(err => {console.error(err)});
Make sure to install the required dependencies for this service. Run the following command to install the dependencies.
npm i apollo-server @apollo/gateway --save

Query your federated subgraph

Run the service with node index.js command. Navigate to http://localhost:4000/ in your browser. It will open up Apollo Studio.
You now have a federated graph up and running that uses Fauna as a subgraph. Run the following composed query to make sure everything is working correctly.
query FindProductByID($findProductByIdId: ID!) {
  findProductByID(id: $findProductByIdId) {
    _id
    name
    description
  }
  locations {
    id
    name
  }
 }
In the Variables field you will need to supply a product ID from your Fauna DB:
ProductID
Once you’ve supplied your variables, make sure you pass in the authorization header. Use the Fauna secret key as the token for our authorization header.Your authorization header should be the following format Bearer fnAEukxxx:
Pass in the authorization header
The previous query returns a composed response from Fauna and locations microservice.
If you’d like to continue exploring federation with the subgraphs we created above, you can find the code for this example in this repository.

Conclusion

Combining Apollo Federation and Fauna allows engineers to be flexible, anticipate future API changes, and implement them easily without "breaking changes". In modern application development, engineering time is the most valuable resource. Apollo Federation and Fauna both focus on developer experience, helping engineers to be more productive and ship features faster at scale.
Have questions about using Fauna with Apollo Federation? Join the Fauna community channels and we would be happy to answer any questions you have. If you want to learn more about the Apollo Community forum. For more reference architecture and code examples with Fauna and Apollo, follow fauna labs on github.

If you enjoyed our blog, and want to work on systems and challenges related to globally distributed systems, serverless databases, and GraphQL, Fauna is hiring!

Share this post

TWITTERLINKEDIN
‹︁ PreviousNext ›︁

Subscribe to Fauna's newsletter

Get latest blog posts, development tips & tricks, and latest learning material delivered right to your inbox.