Search code examples
jsoncurlgithubgraphqlgithub-api

GraphQL complex cURL query (GitHub API v4)


I'm trying to do a GraphQL query to GitHub v4 API in a JS app but I'm having a "Problem with JSON" error. So I'm trying to do it with cURL but it seems to have a problem I can't see.


    curl -H "Authorization: token bearer" -H  "Content-Type:application/json" -X POST -d '{ "query": "query {
      viewer {                                                             
        watching(first: 3, orderBy: {field: UPDATED_AT, direction: DESC}) {
          nodes {                                                                                            
            refs(refPrefix: \"refs/heads/\", orderBy: {direction: DESC, field: TAG_COMMIT_DATE}, last: 100) {
              nodes {   
                target {         
                  ... on Commit {       
                    history(first: 10) {
                      ...CommitFragment
                    }
                  }
                }
              }
            }
          }
        }
      }          
      rateLimit {
        limit
        cost     
        remaining
        resetAt
      }
    }

    fragment CommitFragment on CommitHistoryConnection {
      nodes {  
        message 
        author {
          name               
          avatarUrl(size: 30)
        }
      }
    }                                  

I want to mention that the request is working on the github.com/v4/explorer/ website. And I have escaped the quotes...


Solution

  • The problem is that the query is JSON stringified, in your request you add new lines in the JSON string field query which is not permitted :

    curl -H "Authorization: token YOUR_TOKEN" \
         -H  "Content-Type:application/json" \
         -d '{ 
              "query": "{ viewer { watching(first: 3, orderBy: {field: UPDATED_AT, direction: DESC}) { nodes { refs(refPrefix: \"refs/heads/\", orderBy: {direction: DESC, field: TAG_COMMIT_DATE}, last: 100) { nodes { target { ... on Commit { history(first: 10) { ...CommitFragment } }}}}}}} rateLimit { limit cost remaining resetAt}}fragment CommitFragment on CommitHistoryConnection { nodes { message author { name avatarUrl(size: 30) } } }"
          }' https://api.github.com/graphql
    

    You can also use parameter expansion to remove new lines and escape double quotes :

    token="YOUR_TOKEN"
    query='{
      viewer {
        watching(first: 3, orderBy: {field: UPDATED_AT, direction: DESC}) {
          nodes {
            refs(refPrefix: "refs/heads/", orderBy: {direction: DESC, field: TAG_COMMIT_DATE}, last: 100) {
              nodes {
                target {
                  ... on Commit {
                    history(first: 10) {
                      ...CommitFragment
                    }
                  }
                }
              }
            }
          }
        }
      }
      rateLimit {
        limit
        cost
        remaining
        resetAt
      }
    }
    
    fragment CommitFragment on CommitHistoryConnection {
      nodes {
        message
        author {
          name
          avatarUrl(size: 30)
        }
      }
    }'
    queryStr="${query//[$'\n|\r\n']}"
    
    curl -s -H "Authorization: token $token" \
         -H  "Content-Type:application/json" \
         -d '{ 
              "query": "'"${queryStr//[\"]/\\\"}"'"
          }' https://api.github.com/graphql
    

    In case of Javascript, if you use XMLHttpRequest :

    var http = new XMLHttpRequest();
    var url = "https://api.github.com/graphql";
    http.open("POST", url, true);
    
    http.setRequestHeader("Content-type", "application/json");
    http.setRequestHeader("Authorization", "token YOUR_TOKEN");
    
    http.onreadystatechange = function() {
        if (http.readyState == 4 && http.status == 200) {
            alert(http.responseText);
        }
    }
    
    http.send(JSON.stringify({
        "query": '{ viewer { watching(first: 3, orderBy: {field: UPDATED_AT, direction: DESC}) { nodes { refs(refPrefix: "refs/heads/", orderBy: {direction: DESC, field: TAG_COMMIT_DATE}, last: 100) { nodes { target { ... on Commit { history(first: 10) { ...CommitFragment } }}}}}}} rateLimit { limit cost remaining resetAt}}fragment CommitFragment on CommitHistoryConnection { nodes { message author { name avatarUrl(size: 30) } } }'
    }));
    

    You can also find examples using apollo-client and graphql.js