neo4j-labs / arrows.app

A graph drawing application
https://arrows.app
Apache License 2.0
107 stars 16 forks source link

Export "Data Models" as "Graphql Type Definitions" #32

Closed shivam-880 closed 3 years ago

shivam-880 commented 3 years ago

Seems like there is a one-to-one mapping between "Data Models" built in Arrows.app and Neo4j Graphql "Type Definitions" and it should be possible to export data models as type definitions.

Example Data Model

data model

Example Neo4j GraphQL Type Definitions

#schema.graphql
type Year {
    year: Int! @unique
    movies: [Movie] @relationship(type: "RELEASED_IN", direction: IN)
    peopleBorn: [Person] @relationship(type: "BORN_IN", direction: IN)
    peopleDied: [Person] @relationship(type: "DIED_IN", direction: IN)
}

type Genre {
    type: String! @unique
    movies: [Movie] @relationship(type: "IN_GENRE", direction: IN)
}

type Movie {
    movieId: ID! 
    title: String! @unique
    runtime: Int!
    adult: Boolean!
    avgRating: Float!
    numVotes: Int!
    genres: [Genre] @relationship(type: "IN_GENRE", direction: OUT)
    releasedInYear: [Year] @relationship(type: "RELEASED_IN", direction: OUT)
    directors: [Person] @relationship(type: "DIRECTOR_IN", direction: IN)
    writers: [Person] @relationship(type: "WRITER_IN", direction: IN)
    actors: [Person] @relationship(type: "ACTOR_IN", direction: IN)
    actress: [Person] @relationship(type: "ACTRESS_IN", direction: IN)
    composers: [Person] @relationship(type: "COMPOSER_IN", direction: IN)
    productionDesigners: [Person] @relationship(type: "PRODUCTION_DESIGNER", direction: IN)
    editors: [Person] @relationship(type: "EDITOR_IN", direction: IN)
    cinematographers: [Person] @relationship(type: "CINEMATOGRAPHER_IN", direction: IN)
    archiveFootages: [Person] @relationship(type: "ARCHIVE_FOOTAGE_IN", direction: IN)
}

type Person {
    personId: ID!
    name: String!
    professions: [String!]!
    bornInYear: Year @relationship(type: "BORN_IN", direction: OUT)
    diedInYear: Year @relationship(type: "DIED_IN", direction: OUT)
    directorInMovies: [Movie] @relationship(type: "DIRECTOR_IN", direction: OUT)
    writerInMovies: [Movie] @relationship(type: "WRITER_IN", direction: OUT)
    actorInMovies: [Movie] @relationship(type: "ACTOR_IN", direction: OUT)
    actressInMovies: [Movie] @relationship(type: "ACTRESS_IN", direction: OUT)
    composerInMovies: [Movie] @relationship(type: "COMPOSER_IN", direction: OUT)
    productionDesignerInMovies: [Movie] @relationship(type: "PRODUCTION_DESIGNER", direction: OUT)
    editorInMovies: [Movie] @relationship(type: "EDITOR_IN", direction: OUT)
    cinematographerInMovies: [Movie] @relationship(type: "CINEMATOGRAPHER_IN", direction: OUT)
    archiveFootageInMovies: [Movie] @relationship(type: "ARCHIVE_FOOTAGE_IN", direction: OUT)
}

Example Data

graph

apcj commented 3 years ago

Hi @iamsmkr thanks very much taking the time create this example.

On the face of it, adding another export format would not be difficult, and other export formats have already been requested - see #8.

One thing I would like to clarify, does the arrows proprt-graph model contain all the information needed to specify a GraphQL schema? I notice a few differences comparing the model and the schema in your example. Specifically:

Many thanks!

shivam-880 commented 3 years ago

@apcj personId is mentioned in the property graph model. I added !! for my personal interpretation. Sorry it leaked in the example here. To me: first ! means unique and second ! means mandatory. Probably, these interpretations could be ignored,

danstarns commented 3 years ago

@iamsmkr Thank you for a great suggestion. We have implemented the first pass of this, please try it out, we would love to hear your thoughts.

shivam-880 commented 3 years ago

@danstarns How/Where do I try it? I don't see any option to export the property graph model as type definitions.

danstarns commented 3 years ago

@danstarns How/Where do I try it? I don't see any option to export the property graph model as type definitions.

Try hard-refreshing.

shivam-880 commented 3 years ago

Couple of suggestions:

  1. I think it would be better to use camel cases for any property name. For example, "actor_in" could be named instead as "actorIn".
  2. Relationships in property graph models are mostly "many-to-many" in nature. Hence they must of lists. For example, "actor_in: Movie" should be "actorIn: [Movie]"
  3. I have created another enhancement request for syntax highlighting. https://github.com/neo4j-labs/arrows.app/issues/35
danstarns commented 3 years ago

Couple of suggestions:

  1. I think it would be better to use camel cases for any property name. For example, "actor_in" could be named instead as "actorIn".
  2. Relationships in property graph models are mostly "many-to-many" in nature. Hence they must of lists. For example, "actor_in: Movie" should be "actorIn: [Movie]"
  3. I have created another enhancement request for syntax highlighting. Add syntax highlighting in export code for "json", "cypher" and "graphql" #35

For point 2. You can wrap the relationship type in braces like the image attached: image

shivam-880 commented 3 years ago

@danstarns Relationship properties aren't currently supported by Neo4j GraphQL library (please follow the link below) but you may have to consider it too when supported. https://stackoverflow.com/questions/67985760/how-to-create-a-relationship-property-in-graphql-type-definitions-using-neo4j-gr

apcj commented 3 years ago

@iamsmkr thanks again for this suggestion. And thanks to @danstarns for implementing this! I'm going to close this issue now, but please feel free to open other issue for specific enhancements - as you have already done!