How to access the graphql using Java


#1

The following curl command is works fine

curl -i -H "Authorization: bearer myGithubToken" -X POST -d '{"query": "query { repository(owner: \"wso2-extensions\", name: \"identity-inbound-auth-oauth\") { object(expression:\"83253ce50f189db30c54f13afa5d99021e2d7ece\") { ... on Commit { blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\") { ranges { startingLine endingLine age commit { message url history(first: 2) { edges { node {  message url } } } author { name email } } } } } } } }"}' https://api.github.com/graphql

now I need to call the same in Java as I need to manipulate the outputs. Here is the code that I have tried,

public void callGraphqlApi(){
CloseableHttpClient httpClientForGraphql = null;
CloseableHttpResponse httpResponseFromGraphql= null;

httpClientForGraphql=HttpClients.createDefault();
HttpPost httpPost= new HttpPost("https://api.github.com/graphql");

String query= "query\":\"query { repository(owner: \"wso2-extensions\", name:\"identity-inbound-auth-oauth\") { object(expression: \"83253ce50f189db30c54f13afa5d99021e2d7ece\") { ... on Commit { blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\") { ranges { startingLine endingLine age commit { message url history(first: 2) { edges { node { message url } } } author { name email } } } } } } } }";


httpPost.addHeader("Authorization","Bearer myGithubToken");

try {

    StringEntity params= new StringEntity(query);

    httpPost.addHeader("content-type","application/x-www-form-urlencoded");
    httpPost.setEntity(params);
    httpResponseFromGraphql= httpClientForGraphql.execute(httpPost);

} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}


catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

}

but when I debug the code it gave me this error

HttpResponseProxy{HTTP/1.1 400 Bad Request [Server: GitHub.com, Date: Fri, 03 Feb 2017 12:14:58 GMT, Content-Type: application/json; charset=utf-8, Content-Length: 89, Status: 400 Bad Request, X-RateLimit-Limit: 200, X-RateLimit-Remaining: 187, X-RateLimit-Reset: 1486125149, X-OAuth-Scopes: repo, user, X-Accepted-OAuth-Scopes: repo, X-GitHub-Media-Type: github.v3; format=json, Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, Access-Control-Allow-Origin: *, Content-Security-Policy: default-src ‘none’, Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, X-Content-Type-Options: nosniff, X-Frame-Options: deny, X-XSS-Protection: 1; mode=block, X-GitHub-Request-Id: CF0A:0EE1:B057F26:EBCB8DF:58947441] ResponseEntityProxy{[Content-Type: application/json; charset=utf-8,Content-Length: 89,Chunked: false]}}

What I am doing wrong?


#2

I found a way to get what the output by running the above curl command inside java. Here is the code that I am currently using

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

    public class Demo {
        public static void main(String[] args) {
        
            String url="https://api.github.com/graphql";
               String[] command = {"curl", "-H" ,"Authorization: Bearer myGitHubToken","-H","Accept:application/json","-X", "POST", "-d", "{\"query\": \"query { repository(owner: \\\"wso2-extensions\\\", name: \\\"identity-inbound-auth-oauth\\\") { object(expression:\\\"83253ce50f189db30c54f13afa5d99021e2d7ece\\\") { ... on Commit { blame(path: \\\"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\\\") { ranges { startingLine endingLine age commit { message url history(first: 2) { edges { node { message url } } } author { name email } } } } } } } }\"}" , url};
                ProcessBuilder process = new ProcessBuilder(command); 
                Process p;
                try
                {
                    p = process.start();
                     BufferedReader reader =  new BufferedReader(new InputStreamReader(p.getInputStream()));
                        StringBuilder builder = new StringBuilder();
                        String line = null;
                        while ( (line = reader.readLine()) != null) {
                                builder.append(line);
                                builder.append(System.getProperty("line.separator"));
                        }
                        String result = builder.toString();
                        System.out.print(result);

                }
                catch (IOException e)
                {   System.out.print("error");
                    e.printStackTrace();
                }
        }

}

But according to my view running curl commands inside java is not a good practice. Can you please be kind enough to provide me a way of getting the above output in java other that running curl commands. ( liking using apache httpClient or URLConnection class)


#3

:wave: @kasunsiyambalapitiya,

Let me start by saying that my Java skills are pretty terrible :laughing:,

But looking at your Java snippet, I think that there may be a problem parsing the JSON value of query:

String query= "query\":\"query { repository(owner: \"wso2-extensions\", name:\"identity-inbound-auth-oauth\") { object(expression: \"83253ce50f189db30c54f13afa5d99021e2d7ece\") { ... on Commit { blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\") { ranges { startingLine endingLine age commit { message url history(first: 2) { edges { node { message url } } } author { name email } } } } } } } }";

I believe you’d have to start that out with a { in order to be valid JSON. Looking at your second comment’s curl snippet, you have the appropriate curly braces for valid JSON.

I’d try modifying your first snippet to something like:

String query= "{\"query\": \"query { repository(owner: \\\"wso2-extensions\\\", name: \\\"identity-inbound-auth-oauth\\\") { object(expression:\\\"83253ce50f189db30c54f13afa5d99021e2d7ece\\\") { ... on Commit { blame(path: \\\"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\\\") { ranges { startingLine endingLine age commit { message url history(first: 2) { edges { node { message url } } } author { name email } } } } } } } }\"}"

In the event that isn’t helpful, there should be a more helpful error message in the body of the response. For example when trying with your first version of query, the body of the response says:

{
  "message": "Problems parsing JSON",
  "documentation_url": "https://developer.github.com/v3"
}

I hope this helps!


#4

@bswinnerton (little late on this)

I had some issues with forming queries as valid JSON objects (in PHP not Java) as well - if you look at the provided cURL examples provided in the documentation:

curl -H "Authorization: bearer token" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

You’ll notice the outermost { } are on separate lines - I found that omitting those newlines would cause the GraphQL server to return a parse error. (It’s also worth noting that you can’t have any newlines within the actual query “string” itself :stuck_out_tongue:).


#5

:thinking: that’s very odd, @karagenit. I’m not sure that I fully understand, though. Are you saying that you’re unable to send newline-less JSON payload to the server successfully? Does this work?

curl -H "Authorization: bearer token" -X POST -d "{\"query\": \"query { viewer { login }}\"}" https://api.github.com/graphql

#6

:sweat_smile: Well, I can’t seem to replicate it now (of course) - that cURL you gave me works fine. The issue I was having was actually with PHP’s cURL implementation - I could’ve sworn that it wouldn’t accept the query until I added those newlines…however, just tried it a second ago, and it appeared to work fine without them.

    function build_curl($query, $vars="") {
        $json = "{\n"; //HERE'S THOSE PESKY NEWLINES
        $json .= '"query":"'.$query.'"';
        if(strlen($vars) != 0) {
            $json .= ',"variables":'.$vars;
        }
        $json .= "\n}";    
        return $json;
    }

    function get_curl($token, $json) {
        $curl = curl_init("https://api.github.com/graphql");
        $args = array("Content-Type: application/json", "Content-Length: ".strlen($json), "Authorization: bearer $token");
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $args);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_USERAGENT, "GuestAgent");
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }

(the PHP in question, for those interested)

Thanks!