Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL query based on a specific value of a field

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/

like image 405
Raj Rao Avatar asked May 04 '19 00:05

Raj Rao


People also ask

How do you create a nested query in GraphQL?

You can use the object (one-to-one) or array (one-to-many) relationships defined in your schema to make a nested query i.e. fetch data for a type along with data from a nested or related type. The name of the nested object is the same as the name of the object/array relationship configured in the console.


2 Answers

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.

like image 55
David Maze Avatar answered Sep 30 '22 19:09

David Maze


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

Alternatively please have look at GraphQL directives, as sometimes it's required to skip or include the fields on the basis of the values @skip or @include.

The skip directive, when used on fields or fragments, allows us to exclude fields based on some condition.

The include directive, allows us to include fields based on some condition

GraphQL Directives

like image 29
Yugansh Avatar answered Sep 30 '22 19:09

Yugansh