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

Computed Properties

Open dkirchhof opened this issue 7 years ago • 3 comments

Hi,

how could you use computed properties?
an example:

schema:

type Person {
  firstname: String!
  lastname: String!

  fullname: String! # this should be a computed property (could be generated by calling a neo4j function)
  slug: String! # this should be calculated via a javascript function
}

type Query {
  users: [User]!
}

query

{
  users {
    fullname
    slug
  }
}

resulting cypher query:

MATCH (user:User {}) RETURN user { .fullname, .slug } AS user SKIP 0
  1. I could use e.g. the cypher directive to fetch the fullname, am i right?
  2. What about the slug thing? My first idea: I will override the resolve function of the slug field
resolver = { 
  User: {
    fullname: object => sluggify(object.firstname)
  }
}

but then the firstname could be undefined, if it isn't in the gql query. Also the ".slug" call in the cypher query isn't necessary.

In join-monster, there is a solution for this (https://join-monster.readthedocs.io/en/latest/field-metadata/#computed-columns). You can specify the dependencies of a field:

const User = new GraphQLObjectType({
  //...
  fields: () => ({
    fullName: {
      description: 'A user\'s first and last name',
      type: GraphQLString,
      // perhaps there is no 1-to-1 mapping of field to column
      // this field depends on multiple columns
      sqlDeps: [ 'firstname', 'lastname' ],
      resolve: object => `${object.firstname} ${object.lastname}`
    }
  })
})

Do you have any suggestions or ideas?

dkirchhof avatar Jul 05 '18 06:07 dkirchhof

Yes, you should be able to use a @cypher directive for defining a computed field for fullname.

For slug, in order to support implemented field level resolvers we are planning to add a @ignore (or similarly named) directive to exclude the field from the generated Cypher query. See #34

However, the addition of this directive doesn't solve the problem of the dependent fields not being included in the selection set. To support this use case I would propose adding a dependentFields argument to the @ignore directive that takes a list of dependent fields (or a fragment) and ensures those are added to the selection set:


fragment slugDependency on Person {
  firstname
}

type Person {
  firstname: String!
  lastname: String!
  slug: String! @ignore(dependentFields:slugDependency)
}

Would that support your use case?

johnymontana avatar Nov 10 '18 23:11 johnymontana

@johnymontana This would be awesome for fetching data from external sources as well!

Duske avatar Jan 28 '19 14:01 Duske

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

michaeldgraham avatar May 02 '21 04:05 michaeldgraham