Consider a typical custom resolver with inline cypher
import { Driver } from 'neo4j-driver';
interface ResolverContext {
driver: Driver;
}
export const myCustomResolver = async (
_parent: unknown,
args: unknown,
context: ResolverContext,
): Promise<unknown> => {
const { driver } = context;
const session = driver.session({ database: process.env.NEO4J_DATABASE });
const exampleCypherQuery = `
MATCH (person:Person)-[:WORKS_AT]->(company:Company)
RETURN person.name AS personName,
collect(DISTINCT company.name) AS companies
`;
const exampleParams = {
etc: 'etc',
};
const res = await session.run(exampleCypherQuery, exampleParams);
return res;
};
There is nothing that ensures this query is correct. For instance, I could have a typo WORDS_AT
instead of WORKS_AT
and I'd discover that at execution time.
The first solution I attempted was making custom parsers for my SDL to generate the relationship names (in a relationships.ts file) as part of my schema build step. So for instance I can do
import { Driver } from 'neo4j-driver';
import * as r from 'relationsips`
interface ResolverContext {
driver: Driver;
}
export const myCustomResolver = async (
_parent: unknown,
args: unknown,
context: ResolverContext,
): Promise<unknown> => {
// ... etc
const exampleCypherQuery = `
MATCH (person:Person)-[:${r.Person.worksAt.type}]->(company:Company) // <--- here
RETURN person.name AS personName,
collect(DISTINCT company.name) AS companies
`;
// etc
};
Obviously that still left open opportunities for error. For example this might not be a valid connection (accidentally typed Org
instead of Company
So instead I progressed to generating functions that handle all the details.
const exampleCypherQuery = `
MATCH ${r.Person.as("person").worksAt.Company.as("company")} // <-- here
RETURN person.name AS personName,
collect(DISTINCT company.name) AS companies
`;
Slight inspiration from https://jawj.github.io/zapatos/
Note: I'm not thinking going all the way to Gremlin... But something that enables me to express what I want in Cypher in a type safe(r) way.