neo4j-graphql-skill

Build and configure a GraphQL API backed by Neo4j using @neo4j/graphql v7 (current) or v5 (LTS). Covers Neo4jGraphQL constructor, getSchema(), assertIndexesAndConstraints(), type definitions with @node, @relationship (IN/OUT/UNDIRECTED), @cypher for custom resolvers, @authorization/@authentication f

By neo4j-contrib · 527 installs

npx skills add neo4j-contrib/neo4j-skills --skill neo4j-graphql-skill

Source repository · Upstream listing

When to Use Creating a GraphQL API from a Neo4j graph schema with @neo4j/graphql Writing type definitions with @relationship , @cypher , @authorization directives Using OGM for server side programmatic Neo4j access (bypasses GraphQL auth) Configuring auto generated queries, mutations, subscriptions Securing types/fields with JWT or JWKS based @authorization rules Migrating from v5/v6 to v7 (breaking changes below) When NOT to Use Raw Cypher queries outside GraphQL resolvers → neo4j cypher skill Spring Data Neo4j / Java entity mapping → neo4j spring data skill Generic GraphQL without Neo4j — outside scope Version Matrix Version Status Notes v7 Current — use ≥ 7.6.0 @node required; options removed; explicit eq syntax v5 LTS — use ≥ 5.12.15 Older syntax; options: {limit, offset, sort} still valid Default to v7 unless codebase is on v5. Security patches — upgrade before shipping auth: Fix Fixed in Subscriptions accepted an unverified JWT from WebSocket connectionParams (auth/authz bypass) 7.5.6 / 5.12.14 Field level @authentication on a root custom resolver field ignored when the operation type also had type level @authentication (privilege escalation) 7.6.0 / 5.12.15 Step 1 — Install For subscriptions (CDC required): Step 2 — Minimal Server Setup Key Directives @node (v7 required) @relationship — Full Syntax Querying Relationship Properties — Connection API For each relationship with properties: , a {field}Connection field is auto generated. Access rel properties via actorsConnection.edges.properties , not via actors : @cypher — Custom Resolver this refers to the current node in field level @cypher. Parameters are passed as $paramName . @cypher — Field Arguments and extend type @id and @timestamp @alias — Map GraphQL field to Neo4j property @fulltext and @vector Index must exist in Cypher before use. Phrase capable @vector indexes accept maxPhraseLength [7.6.0] to cap embedding cost. Full syntax, generated query shapes, provider config: [references/search directives.md](references/search directives.md). Security — @authentication and @authorization Step 1: Configure JWT in constructor Step 2: Pass token in context Step 3: Apply @authentication and @authorization BEFORE vs AFTER : CREATE supports only AFTER ; READ supports only BEFORE . Auto Generated Operations Operation Generated Name Example Query all {plural} movies(where, sort, limit, offset) Cursor pagination {plural}Connection moviesConnection(first, after, where, sort) Create create{Plural} createMovies(input: [MovieCreateInput!]!) Update update{Plural} updateMovies(where, update) Delete delete{Plural} deleteMovies(where, delete) v7 Filter Syntax (explicit eq ) Nested Mutations OGM — Programmatic Access OGM bypasses GraphQL authorization — use only in trusted server side contexts. Install separately: npm install @neo4j/graphql ogm Subscriptions (CDC Required) Requires Neo4j CDC enabled in FULL mode. See [CDC docs](https://neo4j.com/docs/cdc/current/). Authenticate subscriptions with a verified token in the WebSocket context; a pre decoded jwt is trusted only when set server side (7.5.6 / 5.12.14 stopped trusting client supplied connectionParams JWTs). Schema Control Directives Common Errors Error Cause Fix Type 'X' not found Missing @node on type (v7) Add @node to every node type @cypher field returns null columnName mismatch with RETURN alias Match columnName exactly to RETURN alias Relationship direction mismatch Both sides declare same direction Inverse: if A has direction: OUT , B must have direction: IN assertIndexesAndConstraints throws @id constraint not in DB Add { options: { create: true } } or run CREATE CONSTRAINT manually Auth not applied JWT not in context Pass token: req.headers.authorization in context function 0 results with valid data v7 filter missing eq Use { field: { eq: value } } not { field: value } connectOrCreate not found Removed in v7 Use connect + create separately Memory errors on large mutations Complex Cypher generation Batch mutations; increase server.memory.heap.max size @subscription not generating v7 requires explicit enable Add features: { subscriptions: true } to constructor v6 → v7 Breaking Changes Summary v6 v7 @node optional @node required on every node type options: { limit, sort } limit , sort as direct args { field: value } filter { field: { eq: value } } connectOrCreate nested mutation Removed — use connect + create directed arg on queries queryDirection in @relationship Single rel fields actor: Person Must use list actors: [Person!]! @private directive Removed @unique directive Removed References [Neo4j GraphQL Docs](https://neo4j.com/docs/graphql/current/) — full directive reference, migration guides [GraphAcademy: GraphQL Basics](https://graphacademy.neo4j.com/courses/graphql basics/) — hands on course [GitHub: @neo4j/graphql](https://github.com/neo4j/graphql) — changelog, issues [CDC Setup](https://neo4j.com/docs/cdc/current/) — required for subscriptions [references/search directives.md](references/search directives.md) — @fulltext , @vector , maxPhraseLength Checklist [ ] @node on every GraphQL type representing a Neo4j node (v7 hard requirement) [ ] @id on identity fields (triggers CREATE CONSTRAINT via assertIndexesAndConstraints ) [ ] assertIndexesAndConstraints called on startup with try/catch [ ] @relationship direction correct: OUT = arrow leaves this node, IN = arrow enters [ ] Both sides of relationship declared with inverse directions [ ] @cypher columnName matches RETURN alias exactly [ ] JWT secret or JWKS URL in features.authorization.key ; token passed in context [ ] @authorization filter vs validate chosen deliberately (silent hide vs thrown error) [ ] v7: filters use explicit { field: { eq: value } } syntax [ ] v7: limit / sort passed as direct query args (not options wrapper) [ ] OGM: await ogm.init() called before any ogm.model() usage [ ] Subscriptions: CDC enabled in FULL mode before enabling features.subscriptions [ ] @neo4j/graphql ≥ 7.6.0 (v7) or ≥ 5.12.15 (LTS) — earlier versions have auth bypasses [ ] .env holds credentials; .env in .gitignore