kensho-technologies/graphql-compiler

Explain how OrientDB schema generation works in ReadTheDocs

Opened this issue · 0 comments

Specifically, we should give more insight into how the OrientDB vertex types are mapped to abstract to GraphQL object types and interfaces, explain how the OrientDB hierarchy is represented in GraphQL and explain the design decisions behind these choices. The outdated documentation below might be helpful here. (This documentation was written when there was no interface inheritance in GraphQL, there was no OrientDB schema generation function and OrientDB was the only database target).

Since the GraphQL and OrientDB type systems have different rules, there
is no one-size-fits-all solution to writing the GraphQL schema for a
given database schema. However, the following rules of thumb are useful
to keep in mind:

- Generally, represent OrientDB abstract classes as GraphQL interfaces. In GraphQL's type system,
  GraphQL interfaces cannot inherit from other GraphQL interfaces.
- Generally, represent OrientDB non-abstract classes as GraphQL types, listing the GraphQL
  interfaces that they implement. In GraphQL's type system, GraphQL types cannot inherit from
  other GraphQL types.
- Inheritance relationships between two OrientDB non-abstract classes, or between two OrientDB
  abstract classes, introduce some difficulties in GraphQL. When modelling your data in OrientDB,
  it's best to avoid such inheritance if possible.
- If it is impossible to avoid having two non-abstract OrientDB classes :code:`A` and :code:`B`
  such that :code:`B` inherits from :code:`A`, you have two options:

  - You may choose to represent the :code:`A` OrientDB class as a GraphQL
    interface, which the GraphQL type corresponding to :code:`B` can implement.
    In this case, the GraphQL schema preserves the inheritance relationship between :code:`A` and
    :code:`B`, but sacrifices the representation of any inheritance relationships :code:`A` may
    have with any OrientDB superclasses.
  - You may choose to represent both :code:`A` and :code:`B` as GraphQL types. The tradeoff in
    this case is exactly the opposite from the previous case: the GraphQL schema sacrifices the
    inheritance relationship between :code:`A` and :code:`B`, but preserves the inheritance
    relationships of :code:`A` with its superclasses. In this case, it is recommended to create a
    GraphQL union type :code:`A | B`, and to use that GraphQL union type for any vertex fields
    that in OrientDB would be of type :code:`A`.
- If it is impossible to avoid having two abstract OrientDB classes :code:`A` and :code:`B`
  such that :code:`B` inherits from :code:`A`, you similarly have two options:

  - You may choose to represent :code:`B` as a GraphQL type that can implement the GraphQL interface corresponding
    to :code:`A`. This makes the GraphQL schema preserve the inheritance relationship between
    :code:`A` and :code:`B`, but sacrifices the ability for other GraphQL types to inherit from
    :code:`B`.
  - You may choose to represent both :code:`A` and :code:`B` as GraphQL interfaces,
    sacrificing the schema's representation of the inheritance between :code:`A` and :code:`B`, but
    allowing GraphQL types to inherit from both :code:`A` and :code:`B`. If necessary, you can
    then create a GraphQL union type :code:`A | B` and use it for any vertex fields that in
    OrientDB would be of type :code:`A`.
- It is legal to fully omit classes and fields that are not representable in
  GraphQL. The compiler currently does not support OrientDB's :code:`EmbeddedMap` type nor
  embedded non-primitive typed fields, so such fields can simply be omitted in the GraphQL
  representation of their classes. Alternatively, the entire OrientDB class and all edges that may
  point to it may be omitted entirely from the GraphQL schema.