"Data Normalization" in GraphQL

I’m currently learning how to evolve schemas.

At the beginning, I have a schema as follows:

type Post {
     topic_title: String! @search(by:[fulltext]) # may be ""
     topic_id: Int!                              # @id doesn't support Int for now
     post_id: Int!                               # @id doesn't support Int for now
     body: String! @search(by:[fulltext])
}

And a query as follows:

query Search($q: String!) {
  queryPost(filter: {body: {anyoftext: $q}, or: { topic_title: {anyoftext: $q}}}) {
    body
    topic_title
    topic_id
    post_id
  }
}

This is pretty straightforwards. Only one type, and one query that filters on both fields. There is obviously an external system (a postgres database) involved.

Now I want to evolve the schema to this:

type Post {
     topic: Topic!
     post_id: Int!
     body: String! @search(by: [fulltext])
}

type Topic {
    topic_id: Int!
    title: String! @search(by:[fulltext])
}

This schema is what traditional database people would call a 1NF.

Observe now I cannot perform the same query. The following query would have a different semantics:

query Search($q: String!) {
  queryPost(filter: {body: {anyoftext: $q}}) {
    topic (filter: {title: {anyoftext: $q}}){
        title
        topic_id
    }
    post_id
    body
  }
}

Specifically, the semantics of the first query is that it filters with a OR. But the semantics of the second query is that it filters first by the Post.body THEN filter topics with the given keywords.

Instead I’d have to do something like this:

query MyQuery($q: String!) {
  queryPost(filter: {body: {anyoftext: $q}}) {
    post_id
    body
    topic {
      title
      topic_id
    }
  }
  queryTopic(filter: {title: {anyoftext: $q}}) {
    title
    topic_id
  }
}

This would then require me to do more work to extract first from queryPost then from queryTopic. This isn’t very ideal.

Question: is there a way to compress the results down into a similar structure as the first query? I seem to be missing something fundamental in my graphql education.

1 Like

I believe this would be related to this feature request:

Maybe you can help prioritize this. As I mentioned in this linked thread we use a DQL filter to get IDs and then pass them to GQL filter. Not the ideal method but it sort of works.

Oh dearie me.