neo4j-graphql / neo4j-graphql-js

NOTE: This project is no longer actively maintained. Please consider using the official Neo4j GraphQL Library (linked in README).
Other
609 stars 147 forks source link

Cannot create custom resolvers without @relation #278

Open viktorstrate opened 5 years ago

viktorstrate commented 5 years ago

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.

browndp08 commented 5 years ago

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

mmmoli commented 5 years ago

@viktorstrate Are you happy to share your custom resolver?

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

viktorstrate commented 5 years ago

@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.

bwalsh commented 4 years ago

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

viktorstrate commented 4 years ago

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

benjamin-rood commented 4 years ago

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.

michaeldgraham commented 3 years ago

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