Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Tenable updates Vulnerability Priority Rating scoring method to flag fewer vulnerabilities as critical

      July 24, 2025

      Google adds updated workspace templates in Firebase Studio that leverage new Agent mode

      July 24, 2025

      AI and its impact on the developer experience, or ‘where is the joy?’

      July 23, 2025

      Google launches OSS Rebuild tool to improve trust in open source packages

      July 23, 2025

      EcoFlow’s new portable battery stations are lighter and more powerful (DC plug included)

      July 24, 2025

      7 ways Linux can save you money

      July 24, 2025

      My favorite Kindle tablet just got a kids model, and it makes so much sense

      July 24, 2025

      You can turn your Google Photos into video clips now – here’s how

      July 24, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Blade Service Injection: Direct Service Access in Laravel Templates

      July 24, 2025
      Recent

      Blade Service Injection: Direct Service Access in Laravel Templates

      July 24, 2025

      This Week in Laravel: NativePHP Mobile and AI Guidelines from Spatie

      July 24, 2025

      Retrieve the Currently Executing Closure in PHP 8.5

      July 24, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      FOSS Weekly #25.30: AUR Poisoned, Linux Rising, PPA Explained, New Open Source Grammar Checker and More

      July 24, 2025
      Recent

      FOSS Weekly #25.30: AUR Poisoned, Linux Rising, PPA Explained, New Open Source Grammar Checker and More

      July 24, 2025

      How to Open Control Panel in Windows 11

      July 24, 2025

      How to Shut Down Windows 11

      July 24, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Exploring GitHub CLI: How to interact with GitHub’s GraphQL API endpoint

    Exploring GitHub CLI: How to interact with GitHub’s GraphQL API endpoint

    April 22, 2025

    You might have heard of the GitHub CLI and all of the awesome things you can do with it. However, one of its hidden superpowers is the ability to execute complex queries and mutations through GitHub’s GraphQL API. This post will walk you through what GitHub’s GraphQL API endpoint is and how to query it with the GitHub CLI.

    What is GraphQL?

    Let’s start with the basics: GraphQL is a query language for APIs and a runtime for executing those queries against your data. Unlike traditional REST APIs that provide fixed data structures from predefined endpoints, GraphQL allows clients to request exactly the data they need in a single request. This single-request approach reduces network overhead, speeds up application performance, and simplifies client-side logic by eliminating the need to reconcile multiple API responses—a capability that has been openly available since the specification was open sourced in 2015.

    GraphQL operations come in two primary types: queries and mutations. Queries are read-only operations that retrieve data without making any changes—similar to GET requests in REST. Mutations, on the other hand, are used to modify server-side data (create, update, or delete)—comparable to POST, PATCH, PUT, and DELETE in REST APIs. This clear separation between reading and writing operations makes GraphQL interactions predictable while maintaining the flexibility to precisely specify what data should be returned after a change is made.

    How is GraphQL used at GitHub?

    GitHub implemented GraphQL in 2016 to address limitations of RESTful APIs. This adoption has significantly enhanced the developer experience when working with GitHub data. With the GraphQL endpoint, you can retrieve a repository’s issues, its labels, assignees, and comments with a single GraphQL query. Using our REST APIs, this would have otherwise taken several sets of nested calls.

    Some GitHub data and operations are only accessible through the GraphQL API (such as discussions, projects, and some enterprise settings), others exclusively through REST APIs (such as querying actions workflows, runners, or logs), and some using either endpoint (such as repositories, issues, pull requests, and user information). GitHub’s GraphQL endpoint is accessible at api.github.com/graphql and you can explore the full schema in our GraphQL documentation or through the interactive GraphQL Explorer.

    A key consideration when choosing between the REST API and the GraphQL API is how the rate limits are calculated. As a quick summary for how this is implemented:

    • REST API: Limited by number of requests (typically 5,000 requests per hour for authenticated users and up to 15,000 for GitHub Apps installed in an Enterprise)
    • GraphQL API: Limited by “points” (typically 5,000 points per hour for authenticated users but can go up to 10,000-12,500 points per hour for GitHub Apps)

    Each GraphQL query costs at least one point, but the cost increases based on the complexity of your query (number of nodes requested, connections traversed, etc.). The GraphQL API provides a rateLimit field you can include in your queries to check your current limit status.

    For scenarios where you need to fetch related data that would otherwise require multiple REST calls, GraphQL is often more rate limit friendly because:

    • One complex GraphQL query might cost 5-10 points but replace 5-10 separate REST API calls.
    • You avoid “over-fetching” data you don’t need, which indirectly helps with rate limits.
    • The GraphQL API allows for more granular field selection, potentially reducing the complexity and point cost.

    However, poorly optimized GraphQL queries that request large amounts of nested data could potentially use up your rate limit faster than equivalent REST requests—and quickly run into secondary rate limit issues.

    A quick rule of thumb on deciding between which to use:

    • For querying relational objects, such as GitHub Projects and their issues, GraphQL is often more effective, especially if it’s a discrete number of items.
    • For bulk data of one type or single data points, such as pulling in a list of repository names in an organization, the REST API is often preferred.

    Sometimes there isn’t a right or wrong answer; so as long as the object exists, try one out!

    Why use GitHub CLI for GraphQL?

    While many developers start with GitHub’s GraphQL Explorer on the web, curl, or other API querying tools, there’s a more streamlined approach: using built-in GraphQL support in the GitHub CLI. Before diving into the how-to, let’s understand why GitHub CLI is often my go-to tool for GraphQL queries and mutations:

    1. Authentication is handled automatically: No need to manage personal access tokens manually.
    2. Streamlined syntax: Simpler than crafting curl commands.
    3. Local development friendly: Run queries and mutations right from your terminal.
    4. JSON processing: Built-in options for filtering and formatting results.
    5. Pagination support: Ability to work with cursor-based pagination in GraphQL responses.
    6. Consistent experience: Same tool you’re likely using for other GitHub tasks.

    How to get started with gh api graphql

    First, ensure you have GitHub CLI installed and authenticated with gh auth login. The basic syntax for making a GraphQL query with gh api graphql is:

    gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      query {
        viewer {
          login
          name
          bio
        }
      }
    '
    

    This simple query returns your GitHub username, the name you have defined in your profile, and your bio. The -f flag defines form variables, with query= being the GraphQL query itself.

    Here’s our example output:

    {
      "data": {
        "viewer": {
          "login": "joshjohanning",
          "name": "Josh Johanning",
          "bio": "DevOps Architect | GitHub"
        }
      }
    }
    

    Running queries and mutations

    Basic query example

    Let’s try something more practical—fetching information about a repository. To get started, we’ll use the following query:

    gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      query($owner:String!, $repo:String!) {
        repository(owner:$owner, name:$repo) {
          name
          description
          id
          stargazerCount
          forkCount
          issues(states:OPEN) {
            totalCount
          }
        }
      }
    ' -F owner=octocat -F repo=Hello-World
    

    The -F flag sets variable values that are referenced in the query with $variable.

    Here’s our example output:

    {
      "data": {
        "repository": {
          "name": "Hello-World",
          "description": "My first repository on GitHub!",
          "id": "R_kgDOABPHjQ",
          "stargazerCount": 2894,
          "forkCount": 2843,
          "issues": {
            "totalCount": 1055
          }
        }
      }
    }
    
    💡 Tip: The -H X-Github-Next-Global-ID:1 parameter sets an HTTP header that instructs GitHub’s GraphQL API to use the new global node ID format rather than the legacy format. While your query will function without this header, including it prevents deprecation warnings when referencing node IDs (such as when passing repository.ID in subsequent operations). GitHub recommends adopting this format for all new integrations to ensure long-term compatibility.

    Running mutations

    Mutations work similarly. Here’s how to create a new issue:

    gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      mutation($repositoryId:ID!, $title:String!, $body:String) {
        createIssue(input:{repositoryId:$repositoryId, title:$title, body:$body}) {
          issue {
            url
            number
            title
            body
            state
          }
        }
      }
    ' -F repositoryId="R_kgDOABPHjQ" -F title="Creating issue with GraphQL" -F body="Issue body created via GraphQL!"
    

    Make sure to update the repositoryId parameter with the actual repository’s GraphQL ID (an example of returning a repository’s ID is shown in the basic query above!).

    Here’s our example output:

    {
      "data": {
        "createIssue": {
          "issue": {
            "url": "https://github.com/octocat/Hello-World/issues/3706",
            "number": 3706,
            "title": "Creating issue with GraphQL",
            "body": "Issue body created via GraphQL!",
            "state": "OPEN"
          }
        }
      }
    }
    

    Filtering GraphQL results

    GitHub CLI supports JQ-style filtering for extracting specific parts of the response, which is invaluable when you need to parse just the repository names or URLs from a query for use in automation scripts. Here is an example of using the --jq flag:

    gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      query($owner:String!, $repo:String!) {
        repository(owner:$owner, name:$repo) {
          issues(first:3, states:OPEN) {
            nodes {
              number
              title
              url
            }
          }
        }
      }
    ' -F owner=octocat -F repo=Hello-World --jq '.data.repository.issues.nodes[]'
    

    The --jq flag accepts JQ expressions to process JSON output. This query returns just the array of issues, without the surrounding GraphQL response structure.

    Here’s our example output:

    {
      "number": 26,
      "title": "test issue",
      "url": "https://github.com/octocat/Hello-World/issues/26"
    }
    {
      "number": 27,
      "title": "just for test",
      "url": "https://github.com/octocat/Hello-World/issues/27"
    }
    {
      "number": 28,
      "title": "Test",
      "url": "https://github.com/octocat/Hello-World/issues/28"
    }
    

    We could have modified the --jq flag to just return the issue URLs, like so:

    gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      query($owner:String!, $repo:String!) {
        repository(owner:$owner, name:$repo) {
          issues(first:3, states:OPEN) {
            nodes {
              number
              title
              url
            }
          }
        }
      }
    ' -F owner=octocat -F repo=Hello-World --jq '.data.repository.issues.nodes[].url'
    

    Here’s our example output:

    https://github.com/octocat/Hello-World/issues/26
    https://github.com/octocat/Hello-World/issues/27
    https://github.com/octocat/Hello-World/issues/28
    

    Handling pagination

    GitHub’s GraphQL API limits results to a maximum of 100 items per page, which means you’ll need pagination to retrieve larger datasets.

    Pagination in GraphQL works by returning a “cursor” with each page of results, which acts as a pointer to where the next set of results should begin. When you request the next page, you provide this cursor to indicate where to start.

    The easiest way to handle this pagination in the GitHub CLI is with the --paginate flag, which automatically collects all pages of results for you by managing these cursors behind the scenes. Here’s what that looks like in a query:

    gh api graphql --paginate -H X-Github-Next-Global-ID:1 -f query='
      query($owner:String!, $repo:String!, $endCursor:String) {
        repository(owner:$owner, name:$repo) {
          issues(first:100, after:$endCursor, states:OPEN, orderBy:{field:CREATED_AT, direction:DESC}) {
            pageInfo {
              hasNextPage
              endCursor
            }
            nodes {
              number
              title
              createdAt
            }
          }
        }
      }
    ' -F owner=octocat -F repo=Hello-World
    

    The pageInfo object with its hasNextPage and endCursor fields is essential for pagination. When you use the --paginate flag, GitHub CLI automatically uses these fields to fetch all available pages for your query, combining the results into a single response.

    Here’s our example output:

    {
      "data": {
        "repository": {
          "issues": {
            "pageInfo": {
              "hasNextPage": true,
              "endCursor": "Y3Vyc29yOnYyOpK5MjAyNC0xMi0zMFQxNDo0ODo0NC0wNjowMM6kunD3"
            },
            "nodes": [
              {
                "number": 3708,
                "title": "Creating issue with GraphQL once more",
                "createdAt": "2025-04-02T18:15:11Z",
                "author": {
                  "login": "joshjohanning"
                }
              },
              {
                "number": 3707,
                "title": "Creating issue with GraphQL again",
                "createdAt": "2025-04-02T18:15:02Z",
                "author": {
                  "login": "joshjohanning"
                }
              },
              {
                "number": 3706,
                "title": "Creating issue with GraphQL",
                "createdAt": "2025-04-02T18:14:37Z",
                "author": {
                  "login": "joshjohanning"
                }
              },
              … and so on
            ]
          }
        }
      }
    }
    

    This approach works great for moderate amounts of data, but keep in mind that GitHub’s GraphQL API has rate limits, so extremely large queries might need to implement delays between requests.

    💡 Important limitation: The --paginate flag can only handle pagination for a single connection at a time. For example, when listing repository issues as shown above, it can paginate through all issues, but cannot simultaneously paginate through each issue’s comments. For nested pagination, you’ll need to implement custom logic.

    Building complex scripts: Chaining GraphQL queries together

    When working with GitHub’s GraphQL API, you often need to connect multiple queries to accomplish a complex task. Let’s look at how to chain GraphQL calls together using the GitHub CLI:

    ISSUE_ID=$(gh api graphql -H X-Github-Next-Global-ID:1 -f query='
      query($owner: String!, $repo: String!, $issue_number: Int!) {
        repository(owner: $owner, name: $repo) {
          issue(number: $issue_number) {
            id
          }
        }
      }
    ' -F owner=joshjohanning -F repo=graphql-fun -F issue_number=1 --jq '.data.repository.issue.id') 
    gh api graphql -H GraphQL-Features:sub_issues -H X-Github-Next-Global-ID:1 -f query='
    query($issueId: ID!) {
      node(id: $issueId) {
        ... on Issue {
          subIssuesSummary {
            total
            completed
            percentCompleted
          }
        }
      }
    }' -F issueId="$ISSUE_ID"
    

    Here’s what this shell script is doing:

    1. The first query captures an issue’s ID using the repository name and issue number
    2. The --jq flag extracts just the ID value and stores it in a variable
    3. The second query passes this ID to retrieve a summary of sub-issues

    Here’s our example output:

    {
      "data": {
        "node": {
          "subIssuesSummary": {
            "total": 3,
            "completed": 1,
            "percentCompleted": 33
          }
        }
      }
    }
    

    Take this with you

    The gh api graphql command provides a convenient way to interact with GitHub’s GraphQL API directly from your terminal. It eliminates the need for token management, simplifies query syntax and formatting, and handles basic pagination that would otherwise be complex to implement. Whether you’re running complex queries or simple mutations, this approach offers a streamlined developer experience.

    Next time you need to interact with GitHub’s GraphQL API, skip the GraphQL Explorer on the web and try the GitHub CLI approach. It might just become your preferred method for working with GitHub’s powerful GraphQL API capabilities.

    Install GitHub CLI

    GitHub CLI is a versatile tool to help you build your workflows. Install the latest version today. If you come up with something awesome, please share it in the CLI Discussions section. We’d love to see it!

    The post Exploring GitHub CLI: How to interact with GitHub’s GraphQL API endpoint appeared first on The GitHub Blog.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleUpdate PyTorch ASAP | Kaspersky official blog
    Next Article Gwyddion – SPM data visualization and analysis

    Related Posts

    News & Updates

    EcoFlow’s new portable battery stations are lighter and more powerful (DC plug included)

    July 24, 2025
    News & Updates

    7 ways Linux can save you money

    July 24, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-46687 – QuickJS Heap Buffer Overflow

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-25257 – Fortinet FortiWeb SQL Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-6006 – kiCode111 like-girl SQL Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    How to Build a Word Search Game Using HTML, CSS, and JavaScript

    Development

    Highlights

    Your favorite AI chatbot is lying to you all the time

    June 10, 2025

    Next time you chat with your favorite AI bot, maybe you should do some fact-checking,…

    CVE-2025-6899 – D-Link DI-7300G+/DI-8200G Os Command Injection Vulnerability

    June 30, 2025

    CVE-2025-49812 – Apache HTTP Server mod_ssl TLS Desynchronisation Hijack Vulnerability

    July 10, 2025

    Chinese Hackers Deploy MarsSnake Backdoor in Multi-Year Attack on Saudi Organization

    May 20, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.