neo4j-graphql-js
neo4j-graphql-js copied to clipboard
Computed Properties
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
- I could use e.g. the cypher directive to fetch the fullname, am i right?
- 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?
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 This would be awesome for fetching data from external sources as well!
https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608