Accessing Drupal's JSON API using resources.GetRemote

Any Drupal install has it’s JSON API available at <domain>/jsonapi, if it’s enabled by the webmaster.
A good example is UNESCO’ website.
One can look at what it delivers by simply navigating to it the browser.
Also, retrieving data via getJSON works (let’s leave aside the unmarshal issue for now).
To keep it simple, this produces results:

{{ getJSON "https://www.unesco.org/en/jsonapi"}} <br>

BUT, as @jmooring mentioned here

the data.GetJSON template function will be deprecated in the next minor release.

So it’s time to move on to resources.GetRemote
And so it begins:
Having gone through maître @regispresentation, the GetRemote doc page and the Drupal JSON API overview and GET doc I still cannot produce the necessary code. I can’t get past this:

    {{ $opts := dict
    "method" "GET"
    "headers" ( dict 
        "Accept" "application/vnd.api+json" "Content-Type" "application/vnd.api+json") 
    }}
    {{ with resources.GetRemote "https://www.unesco.org/en/jsonapi" $opts }}
      {{ with .Err }}
        {{ printf "%s" . }}
      {{ end }}
    {{ end }}

Which produces the output:

error calling resources.GetRemote: failed to resolve media type for remote resource "https://www.unesco.org/en/jsonapi"

I tried with and without $opts, also with only "Accept" "application/vnd.api+json" or just with "Content-Type" "application/vnd.api+json" in the dict, but without success,
Obviously, it doesn’t make sense to carry on until I get rid of the error.
Can anyone help, please?

Do this…

site config

[security.http]
# this is a regex, need to escape . and +
mediaTypes=['application/vnd\.api\+json'] 

template

{{ $data := "" }}
{{ $url := "https://www.unesco.org/en/jsonapi" }}
{{ with resources.GetRemote $url }}
  {{ with .Err }}
    {{ errorf "%s" . }}
  {{ else }}
    {{ $data = .Content | transform.Unmarshal }}
  {{ end }}
{{ else }}
  {{ errorf "Unable to get remote resource %q" $url }}
{{ end }}

Explanation…

To protect against malicious intent, the resources.GetRemote function performs a few checks against the response header (content type), the content itself, and the file extension (if any). For example, you can’t use resources.GetRemote to download an executable.

In this case we need to:

a) Add application/vnd.api+json to the allow list
b) Pass the resource’s .Content through transform.Unmarshal instead of passing the resource itself

1 Like

Every time after I get my answer from @jmooring
Every time.

2 Likes

I’ve added a security section to the documentation for resources.GetRemote.

https://gohugo.io/functions/resources/getremote/#security

2 Likes

You can also find a working Drupal + Hugo interface using JSON API here.

2 Likes

I know, thanks.
My plan is to do it with Hugo + Svelte, but it’s a long journey.
Also, I plan to bring a sufficient level of generality to make it possible to connect with APIs from other CMSs

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.