Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Create typedefs automatically by inferring GraphQL Schema from Neo4j #223

Merged
merged 33 commits into from
Apr 29, 2019

Conversation

moxious
Copy link
Contributor

@moxious moxious commented Mar 31, 2019

(Current status: blocked by needed resolution on #235 otherwise this is almost ready)

What this does

  • Rather than requiring user to specify typeDefs and resolvers, this connects to Neo4j and uses two key procedures built into neo4j db.schema.nodeTypeProperties() and db.schema.relTypeProperties() to harvest info about the graph structure. That information is then transformed into a GraphQL schema.

Example Mapping

Given a simple graph schema like this:

(:Customer { name: "David" })-[:BUYS]->(:Product { sku: "123" })

We want in the end:

typedef Customer {
   name: String!
   buys: [Product] @relation(name: "BUYS", direction: "OUT")
}

typedef Product {
  sku: String!
  customers: [Customer] @relation(name: "BUYS", direction: "IN")
}

Design Notes & Decisions discussed with Will

  • Propertyless node labels - supported by adding _id to all nodes.
  • Multi-valent relationships: not yet supported, pending later type union support
  • Metadata harvesting; we will use okapi neo4j built-in procedures at first, which have the drawback that they require more startup time because they exhaustively look at all nodes. APOC is a faster approach from the startup time perspective but may generate incorrect results if the database is consistent.
  • Failure behavior: wherever possible, the module will generate incomplete schema and issue a warning rather than failing.
  • Generation of relationship types, and their inclusion on node types, should be configurable.

@moxious moxious changed the title (WIP) Create typedefs automatically by inferring GraphQL Schema from Neo4j Create typedefs automatically by inferring GraphQL Schema from Neo4j Apr 24, 2019
Copy link
Contributor

@johnymontana johnymontana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is looking good - most simple cases seem to be handled :-)

I left a few comments, let me know what you think.

LocalDateTimeArray: '[LocalDateTime]'
};

return mapping[t] || 'String';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes String the default when a property type is not found in the above mapping object. This is a reasonable default, however, currently this causes problems in the case of a complex type, such as Point, that exists in the database but cannot be serialized into a string properly by the GraphQL layer since it is treated as an object when returned by the Neo4j driver.

Should we instead exclude these properties from the type definitions? I think we could get away with this as is since Point support will be added soon to neo4j-graphql-js, but are there other possible complex database types that aren't handled by neo4j-graphql-js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to be exhaustive on mapping potential neo4j types, but yeah I think I missed "Point".

I don't think we can get away with omitting "Points" though, becuase the auto-gen schema is going to get fed to augment, which will accept the omission I guess. Maybe we need a carve out and to omit those properties pending point support, but ultimately I guess I need some directive, or other way to express that it's a point so that augment can do the right thing. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave this as-is then - with String as the default. And I can add Point to the inferSchema mapping once we support it in neo4j-graphql-js. I think Point is the only complex type not supported by neo4-graphql-js and we plan to add it very soon. So in the meantime Point fields will be treated as strings, I'm OK with that.

@johnymontana johnymontana merged commit 52fce96 into neo4j-graphql:master Apr 29, 2019
@johnymontana
Copy link
Contributor

Thanks @moxious! This is a super cool feature!

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants