GraphQL query based on a specific value of a field

Raj Rao picture Raj Rao · May 4, 2019 · Viewed 9.1k times · Source

I want to be able to retrieve the latest release from GitHub for a specific repo using their GraphQL API. To do that, I need to get the latest release where isDraft and isPrerelease are false. I have managed to get the first part, but cant figure out how to do the "where" part of the query.

Here is the basic query I have gotten (https://developer.github.com/v4/explorer/):

{
  repository(owner: "paolosalvatori", name: "ServiceBusExplorer") {
    releases(first: 1, orderBy: {field: CREATED_AT, direction: DESC}) {
      nodes {
        name
        tagName
        resourcePath
        isDraft
        isPrerelease
      }
    }
  }
}

Which returns:

{
  "data": {
    "repository": {
      "releases": {
        "nodes": [
          {
            "name": "3.0.4",
            "tagName": "3.0.4",
            "resourcePath": "/paolosalvatori/ServiceBusExplorer/releases/tag/3.0.4",
            "isDraft": false,
            "isPrerelease": false
          }
        ]
      }
    }
  }
}

I cant seem to find a way to do this. Part of the reason is that I am new to GraphQL (first time trying to do a query) and I am not sure how to frame my question.

Can one only "query" based on those types that support arguments (like repository and releases below)? Seems like there should be a way to specify a filter on the field values.

Repository: https://developer.github.com/v4/object/repository/

Releases: https://developer.github.com/v4/object/releaseconnection/

Node: https://developer.github.com/v4/object/release/

Answer

David Maze picture David Maze · May 4, 2019

Can one only "query" based on those types that support arguments

Yes: GraphQL doesn't define a generic query language in the same way, say, SQL does. You can't sort or filter a field result in ways that aren't provided by the server and the application schema.

I want to be able to retrieve the latest [non-draft, non-prerelease] release from GitHub for a specific repo using their GraphQl API.

As you've already found, the releases field on the Repository type doesn't have an option to sort or filter on these fields. Instead, you can iterate through the releases one at a time with multiple GraphQL calls. These would individually look like

query NextRelease($owner: String!, $name: String!, $after: String) {
  repository(owner: $owner, name: $name) {
    releases(first: 1,
             orderBy: {field: CREATED_AT, direction: DESC},
             after: $after) {
      pageInfo { lastCursor }
      nodes { ... ReleaseData } # from the question
    }
  }
}

Run this in the same way you're running it now (I've split out the information identifying the repository into separate GraphQL variables). You can leave off the after variable for the first call. If (as in your example) it returns "isDraft": false, "isPrerelease": false, you're set. If not, you need to try again: take the value from the lastCursor in the response, and run the same query, passing that cursor value as the after variable value.