DEV Community

Jake Dohm
Jake Dohm

Posted on

How to make a GraphQL Query (or Mutation!) in PHP with Guzzle

1: Define a Query

First, we're going to start off with creating a query. This will be a simple query that will ask for the "name" field for our site.

$query = 'query { site { name } }';
Enter fullscreen mode Exit fullscreen mode

Now, this works, but it gets awkward and inconvenient to have to keep our whole query on one line. To fix this, we can use a Heredoc which will allow us to break our query into multiple lines.

$query = <<<GQL
  query {
    site {
      name
    }
  }
GQL;
Enter fullscreen mode Exit fullscreen mode

Note: Make sure the ending GQL; statement is not indented at all as that breaks Heredoc syntax.

2: Make the HTTP request

$graphqlEndpoint = 'https://example.com/graphql-api';
$client = new \GuzzleHttp\Client();

$response = $client->request('POST', $graphqlEndpoint, [
  'headers' => [
    // include any auth tokens here
  ],
  'json' => [
    'query' => $query
  ]
]);
Enter fullscreen mode Exit fullscreen mode

This is a pretty standard request, but there are two notable things:

  1. We're making a POST request. All (properly configured) GraphQL endpoints will only accept a POST request.
  2. We're using json not body.
  3. We're not doing any authentication, but you probably will. This will often either be a token you can add as a header, or it will be basic HTTP authentication that you can pass as a top-level option to Guzzle (see docs).

3: Retrieve the response

$json = $response->getBody()->getContents();
$body = json_decode($json);
$data = $body->data;
Enter fullscreen mode Exit fullscreen mode

4: Put it all together

$query = <<<GQL
  query {
    site {
      name
    }
  }
GQL;
$graphqlEndpoint = 'https://example.com/graphql-api';
$client = new \GuzzleHttp\Client();

$response = $client->request('POST', $graphqlEndpoint, [
  'headers' => [
    'Content-Type' => 'application/json',
    // include any auth tokens here
  ],
  'json' => [
    'query' => $query
  ]
]);

$json = $response->getBody()->getContents();
$body = json_decode($json);
$data = $body->data;
Enter fullscreen mode Exit fullscreen mode

Discussion (1)

Collapse
skino2020 profile image
skino • Edited on

Im having a bit of trouble getting this to work within my Laravel application. Im trying to use the Hashnode API to post from my blog. ive got Dev.to and Medium both working perfectly.

this is my query:

        $query           = <<<GQL
mutation {
  createStory(
    input: {
      title: "$post->title"
      contentMarkdown: "<h1> Ahoy </h1>"
      tags: [
        {
          _id: "56744721958ef13879b94c7e"
          name: "General Programming"
          slug: "programming"
        }
      ]
    }
  ) {
    message
    post {
      title
    }
  }
}
GQL;
Enter fullscreen mode Exit fullscreen mode

Ignore the Tags for the moment i haven got that far yet. where you have the h1 tags i want to use a variable called $markdown which is and entire post from my blog converted to markdown. Never gets passed that stage and gives me this error.

[2021-10-16 23:11:52] production.ERROR: Client error: POST https://api.hashnode.com/ resulted in a 400 Bad Request response:
{"errors":[{"message":"Syntax Error: Unterminated string.","locations":[{"line":5,"column":40}],"extensions":{"code":"GR (truncated...)

Cheers, Mike