In this blog I will take you on a technical dive into the new and improved Neo4j GraphQL Library. Since releasing 1.0.0, in April 2021, we have been working hard taking on board all your ideas, suggestions and applying them to the new and improved 2.0.0 release.
Before we dive into what’s changed and how you can migrate to 2.0.0, I would like to take this opportunity to say thanks to all the community members that showed patience and commitment in both reporting issues and also contributing towards making 2.0.0 a reality.
What’s Included? — TL;DR
Check out Darrell’s Blog post here for a quick overview of what’s included and what has changed in 2.0.0.
- Relationship properties
- Cursor-based pagination
- Count queries
- Improvements to the developer experience with union relationship fields
- More comprehensive validation of type definitions
- Internal refactoring and bug fixes
Now that the Neo4j GraphQL integration has a full-time dedicated team behind it, we are able to shape and implement many more features than that of the older Neo4j Labs neo4j-gaphql-js implementation, which has been deprecated. Our aim with this release was to support relationship properties — something that was missing in the 1.0.0 release. We deliberately left out relationship properties so we could get “something out the door” and with a small team it was a lot to implement. Since our 1.0.0 release, we have received extensive requests to support properties on relationships and so this was high on our agenda.
What Are Relationship Properties?
As stated in the previous paragraph, our aim with this release was to support relationship properties. This section will dive deeper into the motivation and use cases around relationship properties and you should walk away knowing how to implement them in your graph.
Let’s dive deeper here. Here we look at the Movie and Actors model:
You could represent this with the following Neo4j GraphQL schema:
Then, you could create a Movie connected to a Person like so:
Workaround Using an Extra Node
Now, this is all good and what not however, what if we wanted to store information about how much screen time a Person had on a Movie? In a data store where relationship properties are not present you would have to construct two relationships with three nodes, the third node would be a ‘join’/’meta’ node with the screen time as a property as such:
You could represent this model with the following Neo4j GraphQL schema:
Then, you could create a Person, Movie Meta and a Movie like so:
Using Relationship Properties
Relationship properties address the problem we face here; an extra node and relationship. Instead of creating unnecessary data in our Graph, we can utilize the existing relationship and store properties on it. Here is what our model would look like:
You could represent this with the following Neo4j GraphQL schema, using an interface, ActedIn, to represent the relationship property fields:
Then you could create a Movie, and a Person, with relationship properties, like so:
I hope this section showcases the power of using relationship properties, and now you have the power and know-how to put them in your data model.
Where Does Relay Come into It?
In order to get relationship properties into our existing auto-generated schema, we knew one of two things; we needed to either break the existing projections or create new fields for each relationship on a node. In 2.0.0, we opted for the latter approach. What this means is that for each relationship on your node you have both the field name and also fieldNameConnection. The connection field is what’s relevant to the relay spec. Each connection is a Relay compliant field where you use cool stuff such as pagination and have access to the relationship properties. This does mean however, you need to traverse the connection in order to access the relationship properties due to the properties being a part of the Relay edge.
Let’s take a closer look at the new fields. Say you have this schema:
You would normally be able to project the following:
Now, with 2.0.0, you can also project the actorsConnectionfield:
The query above is asking for all the Relay compliant fields. You also have the ability to filter, sort and paginate on the connection fields using cursor-based pagnation like so:
The cursor is great for implementing something like infinite scroll.
As we mentioned earlier, in order to access the relationship properties you need to traverse the connection field. Here we have our schema, that’s been slightly adapted to include relationship properties:
Then here we perform a query to get not only the Movies and Actors but also the properties on the relationship between each Movie and Actor:
What Else Can I Do with 2.0.0?
Other than being able to define relationship properties and use Relay-style pagination we added one last feature: count queries.
We realized that when using 1.0.0 that performing paged-based pagination was difficult and you had to define your own custom resolver using the Cypher directive to be able to compute the total number of pages. Now, this release comes with auto-generated count queries. Using the movies schema, used throughout this post, you can perform the follow count query:
Is That a Moth?
Other than the ability to count, I’d like to point out that we did an extensive backlog grooming session fixing many bugs reported by you the community. We feel that this 2.0.0 release unblocks many users both for migrating to the lib but also people stuck on 1.0.0 with existing bugs.
Thanks for reading, I hope this blog equips you with enough information to get started using all our new cool features. Go and check out our Github today and or read our new revamped documentation here. Cheers 🍻
Your In-Depth Guide to Neo4j GraphQL Library 2.0.0 was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.