273  words
  1  minute 
  GraphQL fragments 
 GraphQL fragments
One of the scripts that builds and deploys datasette.io uses a GraphQL query to retrieve information from GitHub about the repositories used for the various Datasette tools and plugins.
That query was very big - over 4,000 lines long!
That’s because it was shaped like this:
{  repo_0: repository(name: "datasette-query-history", owner: "bretwalker") {    id    nameWithOwner    createdAt    openGraphImageUrl    usesCustomOpenGraphImage    defaultBranchRef {      target {        oid      }    }    repositoryTopics(first: 100) {      totalCount      nodes {        topic {          name        }      }    }    openIssueCount: issues(states: [OPEN]) {      totalCount    }    closedIssueCount: issues(states: [CLOSED]) {      totalCount    }    releases(last: 1) {      totalCount      nodes {        tagName      }    }  }  # ...  repo_137: repository(name: "yaml-to-sqlite", owner: "simonw") {    id    nameWithOwner    createdAt    openGraphImageUrl    usesCustomOpenGraphImage    defaultBranchRef {      target {        oid      }    }    repositoryTopics(first: 100) {      totalCount      nodes {        topic {          name        }      }    }    openIssueCount: issues(states: [OPEN]) {      totalCount    }    closedIssueCount: issues(states: [CLOSED]) {      totalCount    }    releases(last: 1) {      totalCount      nodes {        tagName      }    }  }}That block was repeated for every repository - 138 in total!
I figured there was likely a way to do this more efficiently, and it turns out there is: GraphQL fragments.
Here’s that example query rewritten to use fragments instead:
fragment repoFields on Repository {  id  nameWithOwner  createdAt  openGraphImageUrl  usesCustomOpenGraphImage  defaultBranchRef {    target {      oid    }  }  repositoryTopics(first: 100) {    totalCount    nodes {      topic {        name      }    }  }  openIssueCount: issues(states: [OPEN]) {    totalCount  }  closedIssueCount: issues(states: [CLOSED]) {    totalCount  }  releases(last: 1) {    totalCount    nodes {      tagName    }  }}{  repo_0: repository(name: "datasette-query-history", owner: "bretwalker") {    ...repoFields  }  repo_137: repository(name: "yaml-to-sqlite", owner: "simonw") {    ...repoFields  }}Now each additional repo added to the query is only 3 extra lines of GraphQL, not 30!
 GraphQL fragments 
  https://mranv.pages.dev/posts/graphql-fragments/