1

I want to query some data from another domain. I dont want to to do it in JS (client side) because I want the content right in place on the page.

I tried with several options and variations with the fetch plugin:

{% set poi_query %}"query GetPoi($id: ID!) {

account(name: "Account 1") {
    id
    poi(id: $id) {
      id
      title
    }
  }
}"
{% endset %}

{% set client = {
  base_uri : 'https://www.mydomain.com'
} %}

{% set options = {
  headers: {
    "Content-Type": "application/json"
  },
  query: poi_query|json_encode,
  variables: {
    id: craft.app.request.getSegment(3)
  }|json_encode
} %}

{% set results = fetch(client, 'POST', '/graphql?locale=de', options) %}

{{ d(client, 'POST', '', options) }}
{{ d(results.body ?? results) }}

It always returns 400 errors, or Missing Query

1 Answer 1

2

We solved this ourselves last week when we wanted to query an existing, external GraphQL API from inside a CraftCMS website in Twig without using a GraphQL client. I assume that fetch() in your code is the Fetch plugin for CraftCMS.

tldr; Try requesting with the raw query, without any filters or quotes, but group query and variables under json key inside options.

This should work:

{# 1: block-set query without special treatment #}
{% set graphQLQuery %}
query GetPoi($id: ID!) {
account(name: "Account 1") {
    id
    poi(id: $id) {
      id
      title
    }
  }
}
{% endset %}

{% set client = {
  base_uri : 'https://www.mydomain.com'
} %}

{# 2: query and variables under json key #}
{# 3: no filters for query #}
{% set options = {
  json: {
    query: graphQLQuery,
    variables: {
      id: craft.app.request.getSegment(3)
    }
  }
} %}

{% set results = fetch(client, 'POST', '/graphql?locale=de', options) %}

{{ d(results.body ?? results) }}

Three important points:

  1. When defining the query, get rid of the surrounding quotes.
  2. Group your query and variables under a json key which will hold your request body.
  3. Using |json_encode or other filters on the query looks like the right way because it’s working like that in JS, where you wrap the whole body in JSON.stringify(). But for some reason, this doesn’t return data in Craft/Twig. We got several types of errors instead: Unexpected end of document, No query string was present, and 400 Bad request, depending on what we used….

The code above worked for our API after a lot of trial and error, and is rather easy to maintain because changing the query can be copy and pasted from GraphiQL or other sources.

1
  • Hey @jannisborgers , thx for the answer. The "json" option is new to me. It works now! Thank you for the help May 31 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.