cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! Site migration is underway. Expect disruption to service on Thursday, Feb. 9!

integrate neo4j-graphql driver in apollo v4

ankou29666
Node Link

Hi everyone

I tried to setup a GraphQL server with Apollo for my neo4j database following the driver configuration tutorial.

The problem is that page is completely obsolete regards to the Apollo part as the tutorial is (probably, and at least in the best case, as there's no version at all mentionned anywhere so we can only play guesses) made for Apollo V3, while latest is now 4.3 so V4 is probably not that new, and there's been some significant changes between the two.

versions installed (all latest as I'm writing) :

"dependencies":
{
    "@apollo/server": "^4.3.0",
    "@neo4j/graphql": "^3.14.0",
    "dotenv": "^16.0.3",
    "graphql": "^16.6.0",
    "graphql-tag": "^2.12.6",
    "neo4j-driver": "^5.3.0",
    "nodemon": "^2.0.20"
  }

resulting code is this :

 

import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone'
import { gql } from "graphql-tag"

import neo4j from "neo4j-driver"
import  { Neo4jGraphQL } from "@neo4j/graphql"

const typeDefs = gql`
    type User
    {
        uid: ID
        lastName: String
        firstName: String
        dob: Date
        email: String
    }

    type Adhesion
    {
      year: Int
    }

    type Club
    {
        cid: ID
        name: String
    }
`

const neo4jdriver = neo4j.driver 
(
    "neo4j://localhost:7687", 
    neo4j.auth.basic ("neo4j", "testneo4j")
)

// const createQuery = 'CREATE (:Category {name: "verification" })'
// const matchQuery = 'MATCH (p:USER) RETURN p'
// neo4jdriver.session().run(createQuery)
//   .then((results) => 
//   {
//     console.log(results);
//   }).catch((errors) =>
//   {
//   console.log(errors);
//   });

// console.log ("Driver :   ", neo4jdriver)

const neo4jschema = new Neo4jGraphQL ({typeDefs, neo4jdriver})

const apolloserver = new ApolloServer(
{
  schema: await neo4jschema.getSchema(),
  context: ({ req }) => ({ req, executionContext: neo4jdriver }),
})  

const { url } = await startStandaloneServer(apolloserver, 
{
    listen: { port: 4000 }
})

console.log (`Server running at ${url}`)

 

 

when trying to query in apollo's browser tab

 

query 
{
  users 
  {
    uid
    lastName
    firstName
  }
}

 

I'm getting this error in the browser tab :

"message": "A Neo4j driver instance must either be passed to Neo4jGraphQL on construction, or a driver, session or transaction passed as context.executionContext in each request.".
 
As of my understanding, the neo4jdriver is actually passed to the Neo4jGraphQL constructor.
 
The commented neo4jdriver.session().run(createQuery) actually does creates the extra node.
 
The fact is i don't have much experience with javascript, especially concerning all the asynchronous stuff that I don't use in QtQuick / QML, and I must say I'm getting doubts about how I replaced the then method from tutorial by an await clause.
 
I had initially tried this way but I never succeeded in running the server with the .then clauses, which is the reason why I finally came up with the await clause as it is in my top code.
var apolloserver // Otherwise it's local to the then block such that startStandaloneServer couldn't access it

neo4jschema.getSchema().then((schema) => 
{
  apolloserver = new ApolloServer(
  {
    schema,
    context: ({ req }) => ({ req, executionContext: neo4jdriver }),
  })
})  
but it produces me some plugin error in console (doesn't "build")
 
I also tried to cut and paste the startStandaloneServer block along with the console.log line within the then block, but it seems like javascript doesn't like an await clause within a then statement (at least it's what I understand)
 
Does anyone have an idea about how to solve the problem ?
Thanks for your help.
1 ACCEPTED SOLUTION

ankou29666
Node Link

ok I finally found my error and I was expecting it actually was a javascript error but not an async problem.

When you have a dictionnary in javascript, if the key and the variable containing the value have the same name you can write

const schema
{
    typeDefs,
    driver
}

instead of 

const schema
{
    typeDefs: typeDefs,
    driver: driver
}
 

 

and as I had renamed the driver (too ambiguous about what it refers to, I had to write

const neo4jgraphql = new Neo4jGraphQL (
{
    typeDefs, 
    driver: neo4jdriver
})

and now it works

View solution in original post

1 REPLY 1

ankou29666
Node Link

ok I finally found my error and I was expecting it actually was a javascript error but not an async problem.

When you have a dictionnary in javascript, if the key and the variable containing the value have the same name you can write

const schema
{
    typeDefs,
    driver
}

instead of 

const schema
{
    typeDefs: typeDefs,
    driver: driver
}
 

 

and as I had renamed the driver (too ambiguous about what it refers to, I had to write

const neo4jgraphql = new Neo4jGraphQL (
{
    typeDefs, 
    driver: neo4jdriver
})

and now it works