Generate FragmentTypes

What do you think about auto-generating Fragments for each type?

This would come in handy for very complex objects with many childs where you want to fetch all sub-fields from.

Schema:

type Foo {
   name: String!
   child: Child!
   ... 
}

If I’d have an auto-generated fragment:

fragment FooFragment on Foo {
   name: String!
   child: ChildFragment!
   ... 
}

I could just query:

query {
   queryFoo {
      ...FooFragment
   }
}

and get all fields on return.

Now I’d have to specify all fields on all depths manually which can be time-consuming and error-prone.

Also I think that the amount of required work for this feature is minimal. But please correct me if I’m wrong.

@pbassham, want to share the script you wrote that does just this?

1 Like

Yeah, we felt that pain with 100+ types, and I wanted something that was going to keep our queries up to date automatically across our app when we made changes to our schema, and hopefully keep queries from breaking.

It wasnt really intended to be published or anything, so you will probably have to tweak it, but I went ahead and threw it in a Gist to be able to accept and track any changes or contributions. I feel like it could be beefed up since DGraph has its own consistent naming conventions.

https://gist.github.com/pbassham/0da8bc73929e2fabc1c40351b5bd9a04

We have this set to run as a githook when there are any detected changes to our schema file so that it is always up-to-date. (Using Husky and Lint-staged)

It generates export objects that you can then import into other files one by one

import { FRAGS } from '../contexts/Fragments/codeGenFragments'

And use like this…

const myQuery = gql`
  query getSettings ($username: String!) {
    getUser(username: $username) {
      username #String!
      userId #Int Scalar
      hasEmail {
        ...emailFields
      } #Email! #added by NON_NULL
      hasGroupAccess {
        ...groupAccessFields
      } #GroupAccess OBJECT #added by LIST
      isContact {
        ...contactFields
      } #Contact! #added by NON_NULL
      isAccount {
        ...accountFields
      } #Account OBJECT #added by OBJECT
      hasHadActivity {
        ...activityFields
      } #Activity OBJECT #added by LIST
    }
  }
  ${FRAGS.contactFields},
  ${FRAGS.emailFields},
  ${FRAGS.groupAccessFields},
  ${FRAGS.activityFields},
  ${FRAGS.accountFields},
`

Sample export of the generator script:

import gql from 'graphql-tag'

export const FRAGS = {
checkFields: gql`
  fragment checkFields on Check {
    id #ID!
    checkNumber #String!
    amount #Float!
    memo #String Scalar
    cleared #Boolean Scalar
  }`,

contactCategoryFields: gql`
  fragment contactCategoryFields on ContactCategory {
    id #ID!
    slug #String Scalar
    name #String!
    description #String Scalar
    isPublic #Boolean!
    color #String Scalar
  }`,

// ...ditto for each type in your schema

}

Right now it just is for queries, but could be expanded to generate fragments for mutations, subscriptions, etc. Or, other types of files.

I modified this to also create a ‘prettySchema.md’ file in markdown that is much easier to skim than a raw .graphql file sometimes.

I made a separate post on how we setup githooks to always keep these fragments up to date on any schema change, if you are interested in that.

3 Likes