Announcing the Stable Release of the Official Neo4j GraphQL Library 1.0.0

Migrate your application from neo4j-graphql-js to @neo4j-graphql

Darrell Warde
Apr 27 · 9 min read

Following on from our announcement of the beta release, we are excited to announce that the stable release of the official Neo4j GraphQL Library 1.0.0 is now available to download and use!

For those of you hearing about this library for the first time today, welcome! You can find a high-level overview of this library on our product web page.

The Neo4j GraphQL Library consists mostly of an npm package, @neo4j/graphql, which is the successor to the Neo4j Labs project, neo4j-graphql-js. It’s also a complete redesign and rewrite in TypeScript, for that sweet type safety that suits GraphQL and Neo4j so well.

Responsibility for the project has been shifted from Neo4j Labs to Product Engineering. With a team now dedicated to the new library on a full-time basis, expect high-quality support and continuous improvement.

Additionally, with today’s release also comes the stable version 1.0.0 of @neo4j/graphql-ogm, an Object Graph Mapper. This is an amazing programmatic API for manipulating data in your Neo4j database, all powered by your GraphQL type definitions! While it uses @neo4j/graphql under the hood, you don’t have to use them in conjunction.

My name is Darrell. I’m one of the software engineers working on the Neo4j GraphQL Library. I’m fortunate, not only to be working on this exciting product but also to be working with an amazing team who are passionate about bringing native graph data storage to GraphQL.

Today, I’m going to take this opportunity to walk you through a few of the common steps that will be required to migrate an application over to use the new library. Even if you’re not migrating an existing project, do read on to hear about some of the powerful features in today’s release, as well as some of the exciting ideas that we have for the future… 🚀

This blog contains a mixture of code examples from both the new and old libraries, separated under subheadings. If you see a 🚀in a subheading, go ahead and use any of the code there in your @neo4j/graphql application. See a ⚠️? Code in there is for neo4j-graphql-js, which will soon be deprecated!

Migrating to the Neo4j GraphQL Library

The Neo4j GraphQL Library was never intended to be a drop-in replacement for its predecessor. However, the migration process isn’t too complicated. I’m going to take you through the steps of migrating a small but non-trivial GraphQL API through this process.

If you follow Neo4j at all, you’ll know that we love movies! So we’re going to take an example graph that looks like the following:

Out with the Old… ⚠️

The code snippets in this section are for the legacy neo4j-graphql-js library! If you just want to read about the new library, skip ahead to the next section.

Based on the graph above, a simple implementation using the old library might have looked something like the following:

Type definitions for use with neo4j-graphql-js

Points to note in those type definitions are:

  • @relation directives connecting all of our data together
  • An averageRating field to using a @cypher directive to aggregate an average rating for each Movie
  • The unique ID field for the Review type, decorated with the @id directive

Finally, you would have made a schema and hosted it using Apollo Server, as per the following code block:

Creating a schema using neo4j-graphql-js and hosting with Apollo Server

To add a user, movie, and review to the database we have to run a few mutations! Make sure you keep track of the id field of the review so that we can use it to connect our data together next.

Mutations to create nodes using neo4j-graphql-js
Right now, our “graph” isn’t going to look an awful lot like a graph!

With that ID value in hand, we can use it in our next mutations to connect everything together:

Mutations to connect nodes together using neo4j-graphql-js
Finally we have all of our data connected together!

In with the New! 🚀

We need to start by switching over our npm packages from neo4j-graphql-js to @neo4j/graphql using npm or the package manager of your choice:

You’ll note that we’re having to install graphql and neo4j-driver — these are now peer dependencies in the new library, so these need to be installed explicitly.

You’ll be pleased to know that migrating the basic application above is going to be remarkably simple. The most common change is that you will need to rename all of your @relation directives to @relationship, and change the name argument of that directive to be type instead.

The @cypher and @id directives which we have used can remain unchanged.

Your type definitions should now look like the following:

Type definitions for use with @neo4j/graphql

Then you just need to make a few code changes to create a schema with the new library and host it:

  • Change over your require statement (line 2 below)
  • Swap out the old function for making the schema for the new constructor (line 7 below — you’ll notice I’ve passed in the driver here instead of in the context: the driver will be available in the context whichever method you use, so take your pick!)
  • When constructing your Apollo Server instance, make sure you pull the schema out of the constructed Neo4jGraphQL instance!

With these changes made, standing up your server will look like the following:

Creating a schema using @neo4j/graphql and hosting with Apollo Server

Then for the best part. Let’s say I wanted to write another review for a different movie using the nested mutations feature of the new library:

Nested Mutation using @neo4j/graphql

In one mutation, I’m able to create a new movie with a new review connected to it, which in itself is connected to an existing user, before returning all of that nice connected data (but returning no nodes twice by using that filter in the selection set) in one object. Powerful stuff!

Our graph is looking a lot more like a graph at this point!

Nested mutations are a brand new feature, so you might want to migrate the syntax of your mutations first, before considering how you could combine certain mutations later down the line.

You’ll be feeling like a Kung Fu master as you create entire subgraphs in one Mutation!

We envision that client changes are going to form the bulk of migration work, as the structure of queries and mutations has changed a lot:

  • All query and mutation fields are now in camelCase instead of PascalCase, and are also pluralized — CreateMovie has become createMovies.
  • Query and mutation arguments, which were previously at the root, are now nested under commonly named arguments — CreateMovie(title: String!) has become createMovies(input: [MovieCreateInput!]!).
  • Mutation responses now have an additional level until you reach the fields of the mutated node.
  • Specifically relating to the DateTime scalar (as is used in this example), these are now purely dealt with as ISO 8601 strings, so you no longer need to use arguments such as formatted.

You can check out this commit in our repository to see the inline difference, and run the above Nested Mutation if you like!

But Wait, There’s More!

In my opinion, the example above is a little too simple:

  • Any user can author a review under the guise of another user, or edit other users’ reviews
  • The createdAt field needs to be manually set when authoring a review

We should really build on our schema and add the functionality needed to address these shortfalls.

Rolling Your Own Solution Using neo4j-graphql-js ⚠️

The code snippets in this section are for the legacy neo4j-graphql-js library! If you just want to read about the new library, skip ahead to the next section.

I’m not going to go into the detail of implementing an auth solution in this blog. However, using the old library, we would have likely overridden the generated CreateReview mutation with either a custom resolver or a pretty complex @cypher directive using the cypherParams feature (you can do pretty similar thing in the new library, too!).

Whichever method we chose, it would have needed to create a review with createdAt set to the current timestamp, and then connect it to the currently logged-in user, and also to the movie that it addresses.

We would have had added the following mutation type to our type definitions:

Overriding a generated Mutation using neo4j-graphql-js

Using the @isAuthenticated directive, we would have also needed to pass a config object to makeAugmentedSchema specifying which auth directives we want to use:

Auth can be quite complex with neo4j-graphql-js

Using GraphQL Directives for Fun and Profit 🚀

Using the new Neo4j GraphQL Library, I’m happy to say that we offer a number of directives that can essentially remove the need for a custom CreateReview mutation entirely:

@timestamp and @auth directives available in @neo4j/graphql

The directives to note from the code block above are:

  • The @timestamp directive which can be used to automatically set timestamps on create and/or update operations
  • The use of the @auth directive, which in this example is being used to restrict users from creating reviews under the guise of another author, or updating other users’ reviews

This won’t automatically connect your nodes together for you, but it will protect from nefarious users taking credit for reviews that aren’t theirs!

It’s worth noting that you’ll need a method for creating users and dishing out their JWTs, such as a signUp mutation. Using the OGM is a really nice way to achieve this, which I won’t detail in this blog, but you can expect plenty of news in the coming weeks and months.

There’s also less boilerplate when it comes to creating your schema and server — you just need to pass your request into your context object:

Just pass your request into the context and auth is good to go using @neo4j/graphql

Need a Hand?

We realize that hypothetical example applications are very different from the real thing, so we (and the growing community) are on hand to help you figure things out as you migrate.

This blog is by no means comprehensive, so we have written a migration guide which has a bit more fine-grained detail of schema, query, and mutation differences. This will be an evolving document that will grow and change as we continue development on the new library.

If you believe we’ve missed some functionality that should be there or something isn’t working quite as you’d expect it to, please raise an issue in our GitHub repository.

If you want to ask us or the community for a hand (or generally want to chat Neo4j and GraphQL!), please join the Neo4j Discord server where you can find a #graphql channel and a variety of other great topics to discuss.

You can also check out the GraphQL and GRANDstack category in the Neo4j Online Community.

Where Do We Go from Here?

Don’t worry, this certainly isn’t the end of development for the Neo4j GraphQL Library. Below you can find just a small insight into some of the ideas that the team has for future functionality.

Relay Implementation

If you have used them in your current neo4j-graphql-js applications, you have likely noticed the absence of relationship properties in this release. While we realize this prevents immediate migration for a number of users, we’re aiming for this to be one of the first major features we look at after today’s release.

After plenty of discussions, we believe that implementing the Relay specification is going to provide the perfect framework for introducing relationship properties. Additionally, it will allow us to add in the much-requested feature of cursor-based pagination to help you build applications with infinite scrolling.

Aggregations

We’re pleased with the comprehensiveness of the current filters offered by the Neo4j GraphQL Library, but we want to expand these further with aggregations, allowing you to query averages, sums, and more.

Have Amazing Ideas for Neo4j and GraphQL?

On Global Graph Celebration Day, Neo4j announced the Leonhard Euler Idea Contest. This is a hackathon running from April 27 until June 4, and we want to see you turn your innovative ideas into reality using our new GraphQL library!

Not only is this an amazing opportunity to get hands on with the new library, there are also $10,000 worth of prizes available and an opportunity to gain access to Aura Free Tier for early registrants! Registration is now open.

Neo4j Developer Blog

Developer Content around Graph Databases, Neo4j, Cypher…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store