Generate GraphQL CRUD API
The Neo4j GraphQL Library automatically creates Query and Mutation types from your type definitions
that provide instant CRUD functionality. The GraphQL CRUD API can be configured and extended, and helps define the database schema and the GraphQL schema with the same type definitions.
type Movie {
title: String!
actors: [Person!]!
@relationship(type: "ACTED_IN", direction: IN)
}
type Person {
name: String!
}
{
movies(where: { title: "River Runs Through It" }) {
title
actors {
name
}
}
}
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WHERE m.title = "River Runs Through It"
RETURN *
Generate Cypher from GraphQL
The Neo4j GraphQL Library generates a single Cypher query to resolve any arbitrary GraphQL request.
This means the resolvers are automatically implemented for your scenario. No need to write
boilerplate
data fetching code – just inject a Neo4j driver instance into the request context and the Neo4j GraphQL
Library takes care of generating the database query and handling the database call. Additionally,
since a
single Cypher query is generated, this results in a huge performance boost and eliminates the N+1
query
problem.
Extending GraphQL with Cypher
Since GraphQL is an API query language and not a database query language, it lacks semantics for
operations such as aggregations, projections, and more complex graph traversals.
You can now extend the power of GraphQL through the use of @cypher GraphQL schema directives to
bind the
results of a Cypher query to a GraphQL field. This allows for the expression of complex logic using
Cypher
and can be used on Query and Mutation fields to define custom data fetching or mutation logic.
The Neo4j native graph database makes complex and multi-hop graph traversals highly performant to
provide
blazing-fast query response for your applications.
type Movie {
title: String!
actors: [Person!]!
@relationship(type: "ACTED_IN", direction: IN)
similar(first: Int = 3): [Movie!]!
@cypher(
statement: """
MATCH (this)<-[:ACTED_IN|:DIRECTED]-(o)-[:ACTED_IN|:DIRECTED]->(rec:Movie)
WITH rec, COUNT(*) AS score
RETURN rec ORDER BY score DESC LIMIT $first
"""
)
}
type Person {
name: String!
}
type Movie {
title: String!
actors: [Person!]!
@relationship(type: "ACTED_IN", direction: IN)
}
type Person {
name: String!
}
extend type Movie
@auth(
rules: [{ operations: [UPDATE], allow: { actors: { name: "$jwt.sub" } } }]
)
Secure APIs with Built-In Auth
Neo4j GraphQL Library comes with an Auth directive out-of-the-box for enabling authorization rules
to
GraphQL API using JSON Web Tokens (JWTs).
Having lots of different approaches to securing GraphQL API puts some beginners off. With the Auth
directive, we have reduced a lot of complexity that comes with building a secure GraphQL API.
Including
Auth provides a working solution to users wanting to quickly and easily "spin up" secure services.
Also,
the power of Cypher effectively enables the library to translate complex authorization rules into a
single
Cypher query.
type Movie {
title: String!
actors: [Person!]!
@relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn")
}
type Person {
name: String!
}
interface ActedIn {
roles: [String!]!
}
Easily Add Relationship Properties
Adding relationships into your data model gives your data the context it needs to run complex queries across wide sections of your graph.
With GraphQL Library, you are able to define an interface that represents your relationship properties. This can be used with multiple relationships simply by adding the properties key to your existing relationship directives. The result is a great developer experience when incrementally growing applications.
Cursor-Based Pagination
Cursor-based pagination is the preferred method for delivering an infinite scroll on the frontend. The biggest advantage of cursor-based pagination is its ability to handle real-time data changes effectively. This is because cursors do not require the data to remain static – when records are added or removed, each new page still loads correctly.
With GraphQL Library, you get cursor-based pagination for all relationship fields, with the great filtering and sorting you’re already familiar with.
{
movies(where: { title: "River Runs Through It" }) {
title
actorsConnection(first: 10, after: "opaqueCursor") {
edges {
roles
node {
name
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}