neo4j-graphql-js icon indicating copy to clipboard operation
neo4j-graphql-js copied to clipboard

Cannot create custom resolvers without @relation

Open viktorstrate opened this issue 4 years ago • 7 comments

I am making a photo gallery site, and photo urls are generated on the server and not managed by the neo4j database.

This is currently my typedefs:

type PhotoURL {
  thumbnail: String
  original: String
}

type Photo {
  id: ID!
  title: String
  path: String!
  url: PhotoURL @relation(name: "NOTHING", direction: "IN")
}

I have a custom resolver for the url field on for the Photo type. But it throws an error if I remove the dummy relationship @relation(name: "NOTHING", direction: "IN"), even though I have a custom resolver defined.

It would probably be better, if the field was ignored when a custom resolver is defined, instead of throwing an error.

Stack-trace for error if relationship is removed

TypeError: Cannot read property '0' of undefined",
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:321:20)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:181:12)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:206:22)
            at recurse (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:83:33)
            at buildCypherSelection (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/selections.js:181:12)
            at nodeQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/translate.js:584:69)
            at translateQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/translate.js:491:12)
            at cypherQuery (/Users/viktorstrate/Development/photoview/api/node_modules/neo4j-graphql-js/dist/index.js:146:40)

EDIT: Found out that @neo4j_ignore can be used instead, but this still shouldn't be necessary if a custom resolver was found.

viktorstrate avatar Jul 16 '19 09:07 viktorstrate

I agree, it shouldn't be necessary and it would be quite helpful if @neo4j_ignore was added to the documentation.

browndp08 avatar Jul 26 '19 20:07 browndp08

@viktorstrate Are you happy to share your custom resolver?

I'm hoping it'll help me get to the bottom of #144.

mmmoli avatar Aug 05 '19 17:08 mmmoli

@mmmoli, I came by the issue, when developing my side project Photoview.

I've created a new branch on the project, to make it easier to setup a proof of concept.

Steps to reproduce

  1. Clone the branch: $ git clone --branch issue478 https://github.com/viktorstrate/photoview.git

  2. Start a Neo4j server with username neo4j and password letmein, running on the default host (bolt://localhost:7687)

  3. Start the back-end server $ cd api $ npm install $ npm run start-dev The graphql playground should then be available at http://localhost:4001/graphql

  4. Make dummy photo, by running the following Cypher query: CREATE (p:Photo { title: 'Test Photo' })

  5. Run the following Graphql query, in the playground

query {
  Photo {
    title
    thumbnail {
      path
    }
} }

And you should get the following result:

{
  "data": {
    "Photo": [
      {
        "title": "Test Photo",
        "thumbnail": {
          "path": "http://localhost:4001/images/undefined/thumbnail.jpg"
        }
} ] } }
  1. Now change the schema located at api/src/schema.graphql. Find the Photo type and remove @neo4j_ignore

  2. Rerun the Graphql query in the playground from step 5, you should now get the "Cannot read property '0' of undefined" error. You might have to restart the server, before the schema is updated.

viktorstrate avatar Aug 05 '19 20:08 viktorstrate

@viktorstrate Thanks very much for an excellent explanation and example project to illustrate the problem.
Saved me a bunch of time. Nice Work!

bwalsh avatar Feb 19 '20 18:02 bwalsh

@bwalsh You are very welcome 😊 I'm glad it helps!

viktorstrate avatar Feb 19 '20 19:02 viktorstrate

Another hack/workaround is to annotate the field with a redundant @cypher directive. Either way, I prefer the text inside the @relation or @cypher statement to say something like DEFINED_IN_RESOLVER! so at least if someone else encounters the code at a glance they know what's up.

@johnymontana Any ideas of how to solve this? Because I've also encountered this when defining custom field resolvers and it's pretty jolly poor. Anyone who has to derive a complicated computed field (something that doesn't directly live in the database or can't be computed within a cypher statement) is going to run into this. It should just work out of the box, the library shouldn't break the resolver pattern.

If it's too difficult to work transparently, then perhaps we could have a custom directive like @use_resolver as an alternative. Because one may well want to expose that field and as such using @neo4j_ignore is a non-option.

benjamin-rood avatar Mar 02 '20 23:03 benjamin-rood

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608

michaeldgraham avatar May 02 '21 04:05 michaeldgraham