graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Feature request: Inline types

Open rmortes opened this issue 2 years ago • 0 comments

I'm currently trying to implement the following schema:

type Entry {
  ...
  content: RichContent
}

enum RichContentType {
  MarkDown
  Image
  Video
  Audio
  HTML
}

type RichContent @exclude {
  type: RichContentType!
  content: String!
}

The idea that I want to represent with this schema is: I have several entries (like blog entries), with some data and a list of rich content. This content is some string that gets parsed differently depending on its type. You can think of this content as the different paragraphs on a blog's body.

Since I want the RichContent / sections to be sequential, and remember their order, I need a way to retrieve them with the same order always.

A relationship is the first thing that came to my mind to solve this problem, but it's got several downsides that make the solution subobtimal:

  1. There is no way (that I know, I'm quite new to the world of graph dbs in general and this package in particular) to easily enforce order in a relationship.
  2. I could create a relationship with an order: Int! property and maybe decorate the field with @computed, but that only covers reading. This solution forces me to create a custom mutation to update the field
  3. A relationship is not the best conceptual solution, since the entity RichContent is an integral part of a single Entry. I won't repeat a paragraph across different blog entries

I'd like a way to mark a type as inline only (maybe with @inline. These "inline types" would be typed nested objects in another type.

With this solution, I should be able to query my schema with a syntax like:

mutation AddContent{
  createChapters(input: [{
    content: [
      {type: "SOME", content: "THING"},
      {type: "HELLO", content: "WORLD"},
    ]
  }]) {
    content
  }
}

mutation UpdateContent{
  createChapters(input: [{
    content: [
      {type: "Hello", content: "World"},
      {type: "Some", content: "Thing"},
    ]
  }]) {
    content
  }
}

mutation RemoveContent{
  createChapters(input: [{
    content: []
  }]) {
    content
  }
}

Thanks

rmortes avatar Jul 07 '22 17:07 rmortes