Apollo Federation
This is the documentation of the GraphQL Library version 6. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS. |
This guide shows how to create a subgraph using the Neo4j GraphQL Library, for composition into a supergraph using Apollo Federation.
The objective is to convert the following monolithic schema into a subgraph schema for use behind a Federation gateway:
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { Neo4jGraphQL } from "@neo4j/graphql";
import neo4j from "neo4j-driver";
const typeDefs = `#graphql
type User @node {
id: ID!
name: String!
}
`;
const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic("username", "password"));
const neo4jGraphQL = new Neo4jGraphQL({
typeDefs,
driver,
})
const schema = await neo4jGraphQL.getSchema();
const server = new ApolloServer({
schema,
});
const { url } = await startStandaloneServer(server);
console.log(`🚀 Server ready at ${url}`);
Setup
To proceed with the conversion, follow these steps:
-
Create a directory for a new project and
cd
into it:mkdir neo4j-graphql-subgraph-example cd neo4j-graphql-subgraph-example
-
Initialize a new Node.js project with
npm
:npm init --yes npm pkg set type="module"
This how-to guide sets up the project using ES Modules, which allows the usage of features such as top-level
await
. -
Choose TypeScript or JavaScript to proceed with the setup:
-
Create a
src
directory with an emptyindex.js
file to contain the entrypoint to your code:mkdir src touch src/index.js
-
Replace the default
scripts
entry in yourpackage.json
file with the following:{ // ...etc. "scripts": { "start": "node index.js" } // other dependencies }
-
Create a src directory with an empty index.ts file to contain the entrypoint to your code:
mkdir src touch src/index.ts
-
Install the development dependencies required for working with a TypeScript project:
npm install --save-dev typescript @types/node @tsconfig/node-lts
-
Create an empty tsconfig.json file containing the compiler configuration for TypeScript:
touch tsconfig.json
-
Add the following configuration to the tsconfig.json file:
{ "extends": "@tsconfig/node-lts/tsconfig.json", "compilerOptions": { "rootDir": "src", "outDir": "dist", } }
This configuration extends the community base for Node.js LTS, provided by the @tsconfig/node-lts package installed above. For more information on the available options, see the TypeScript Compiler docs.
-
Replace the default scripts entry in your package.json file with the following:
{ // ...etc. "scripts": { "compile": "tsc", "start": "npm run compile && node ./dist/index.js" } // other dependencies }
-
To proceed with the setup, install the required dependencies running the following command:
npm install @apollo/server @neo4j/graphql graphql neo4j-driver
There are the dependencies to be installed:
-
@apollo/server
, the library for Apollo Server, is used in this guide to host the subgraph. -
@neo4j/graphql
is the Neo4j GraphQL Library, which translates GraphQL into Cypher and returns the results. -
graphql
is the reference implementation of the GraphQL specification. It is required for@neo4j/graphql
to function. -
neo4j-driver
is the library for the Neo4j driver, which is required to execute Cypher queries against the database.
-
Opt in to Federation
For a set of type definitions to be usable as a subgraph for Federation, they must include the following schema extension:
const typeDefs = `#graphql
extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"])
type User @node {
id: ID!
name: String!
}
`;
This example only includes the Federation |
Define an entity
Defining a type as an entity allows other subgraphs to contribute with fields to the Movie
type.
To achieve that, use the @key
directive to designate a field (or fields) as a key:
const typeDefs = `#graphql
extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"])
type User @key(fields: "id") @node {
id: ID!
name: String!
}
`;
Although only the @key
directive has been added to this example, consider using either the @id
or the @unique
directives on the id
field.
The Federation gateway expects each key to resolve to one result, so it is good practice to ensure that these values are unique in the database.
Generate a subgraph schema
When using the Neo4j GraphQL Library, generating the subgraph schema can be achieved by calling getSubgraphSchema
instead of getSchema
.
For that, the following line needs to be changed:
const schema = neo4jGraphql.getSubgraphSchema();
Conclusion
By combining all previous snippets, you should get this:
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { Neo4jGraphQL } from "@neo4j/graphql";
const typeDefs = `#graphql
type User @key(fields: "id") @node {
id: ID!
name: String!
}
`;
const driver = neo4j.driver("bolt://localhost:7687", neo4j.auth.basic("username", "password"));
const neo4jGraphQL = new Neo4jGraphQL({
typeDefs,
driver,
})
const schema = await neo4jGraphQL.getSubgraphSchema();
const server = new ApolloServer({
schema,
});
const { url } = await startStandaloneServer(server);
console.log(`🚀 Server ready at ${url}`);
For further iteration, this subgraph can also be composed into a supergraph. Check Apollo’s guides for more instructions: