This issue requests support for a cypher template literal tag for use in writing the Cypher statement argument of @cypher directive fields. Using a cypher tag would result in support for Cypher syntax highlighting in any editor using an extension that provides highlighting support for it, such as the Cypher Query Langauge Tools for Neo4j extension for Visual Studio Code.
This would result in a smoother experience when reading and writing Cypher within a GraphQL schema using @cypher fields, especially for multi-line Cypher statements. A GraphQL block string is currently used to support a multi-line String type directive argument. This results in an absense of syntax highlighting support within such arguments. In the Federation example for the inventory service, the @cypher statement for the shippingEstimate field on the Product entity would normally be as follows:
shippingEstimate: Int
@requires(fields: "weight price")
@cypher(statement: """
CALL apoc.when($price > 900,
// free for expensive items
'RETURN 0 AS value',
// estimate is based on weight
'RETURN $weight * 0.5 AS value',
{
price: $price,
weight: $weight
})
YIELD value
RETURN value.value
""")
An implementation for a cypher tag template for the statement argument of a @cypher directive might look like:
export const cypher = (statement, ...substitutions) => {
// Get the array of string literals
const literals = statement.raw;
// Add each substitution inbetween all
const composed = substitutions.reduce((composed, substitution, index) => {
// Add the string literal
composed.push(literals[index]);
// Add the substitution proceeding it
composed.push(substitution);
return composed;
}, []);
// Add the last literal
composed.push(literals[literals.length - 1]);
// Return the Cypher statement string as a GraphQL block string
// for the `@cypher` directive statement argument
return `statement: """${composed.join('')}"""`;
};
With the Cypher statement argument being provided as the result of the above cypher tag implementation, we could write the shippingEstimate's @cypher statement within another string literal with the tag, used as an embedded expression within the string literal containing the GraphQL schema SDL (which is the case when using a gql tag). The Cypher would then be appropriately highlighted in an editor with Cypher language support for the tag.
shippingEstimate: Int
@requires(fields: "weight price")
@cypher(${cypher`
CALL apoc.when($price > 900,
// free for expensive items
'RETURN 0 AS value',
// estimate is based on weight
'RETURN $weight * 0.5 AS value',
{
price: $price,
weight: $weight
})
YIELD value
RETURN value.value
`})
Using the Cypher Query Langauge Tools for Neo4j extension for Visual Studio Code:

Statements as variables
The Cypher statement of a @cypher directive using a cypher tag could also be elevated to a
variable, which could be imported.
import { cypher } from 'neo4j-graphql-js';
export MATCH_USERS = cypher`
MATCH (users: User)
RETURN users
`;
import { MATCH_USERS } from 'matchUsers.js';
const typeDefs = gql`
type Query {
Users: [User] @cypher(${
MATCH_USERS
})
}
type User {
id: ID!
name: String
}
`;
Validation and analysis
A Cypher statement using a cypher tag could be processed using additional behaviours added
to its implementation, such as validation and analysis.
@michaeldgraham Why did you close this? Sounds useful to me.
It's been implemented in the referenced PR :)
Yay!
Most helpful comment
It's been implemented in the referenced PR :)