Skip to content

Instantly share code, notes, and snippets.

@ptpaterson
Last active January 19, 2018 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptpaterson/02fb930bf973ca10de973ca04fb9253a to your computer and use it in GitHub Desktop.
Save ptpaterson/02fb930bf973ca10de973ca04fb9253a to your computer and use it in GitHub Desktop.
GraphQL to GraphQL+/- conversion discussion

My data is generally pretty unstructured, but can be considered composed of well definable "traits". Facets have been an interesting point. So I am trying to figure out how to group edges to scalars, edges to nodes, and facets together in GraphQL types, suggesting types and queries like:

interface Node {
  uid: String!
  someBaseProperty
}

type User implements Node {
  uid: String!
  someBaseProperty: Int
  name: String!
}

interface trait {
  type: String!
}

type hasFriend implements trait {
  type: String!
  since: DateTime! @facet(friend) // I'm thinking maybe need a directive here
  friend: Node!
}

type Profile implements trait {
  type: String!
  age: Int
  sex: Boolean
  profession: String
}

query {
  Node(uid: "0x1234") {
    otherBaseProperty
    traits {
      ... on has Friend {
        since
        friend { 
          name
        }
      }
      ... on Profile {
        age
        sex
        profession
      }
    }
  }
}

which is A LOT for what I could get with the following GraphQL+/- query.

{
  User(func: eq(uid, "0x1234")) {
    name
    otherBaseProperty
    friend @facets(since: since) {
       name
    }
    age
    sex
    profession
  }
}

This example might be a bit convoluted because it seems like a User type could just have all of those fields in it. But my data is much more unstructured than that. Like if I were tracking of users, as well as real famous people, as well as movie characters, as well as comic book heroes. They may all have friends, but will also have vastly different properties as well. Note that the friend property was pointed to a Node, not another User. To create Types for each permutation of possible connected edges would explode the schema.

In order to help the client sort out how to compose it's queries, I am considering adding trait info to the database. That way, an ititial query could check:

query {
  Node(uid: "0x1234") {
    hasTraits {
      type
    }
  }
}

and then intelligently query with only the ... on TraitType that it really needs.

Why "Traits". We could just search for the edges.

If the edges of your application are all very well structured, then you could create a few types and then the queries would be easy. But I cannot easily declare what types things are ahead of time. With unstructure edges in the graph, it's like every edge would be its own Trait type.

query {
  Node(uid: "0x1234") {
    edges {
      ... on Age {
        age
      }
      ... on Sex {
        sex
      }
      ... on Profession {
        profession
      }
    }
  }
}

So I am trying to reduce the number of GraphQL types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment