0

I am trying to consume PokeAPI using Drupal. For making API calls I am using HTTP Client Manager module. I am able to set up initial configuration and get the data when the response field is a string. But I am not able to get data when the response field is array.Can any one please point out what I am doing wrong.

I am just trying to make a HttpGet request to the following URL

https://pokeapi.co/api/v2/pokemon?offset=300&limit=100

As the API has documentation of their resource Documentation I felt it would be good until I hit the wall of dealing with Array field. If anyone got suggestion for better approach I would like to try it out.

My code is as follows :

pokeapi/pokeapi.http_services_api.yml

pokeapi.base:
  title: "Drupal and PokeAPI Services API"
  api_path: "src/api/pokeapi_services.yml"
  config:
    base_uri: "https://pokeapi.co/"
    debug: "/tmp/pokeapi.log"

pokeapi/src/api/pokeapi_services.yml

name: "Drupal and PokeAPI Services API"
apiVersion: "2.0"
description: "Drupal Client wrapper for the PokeAPI Services API."
imports:
  - "resources/posts.yml"
  # - "resources/models.yml"

pokeapi/src/api/resources/posts.yml

operations:
  GetPokemonsList:
    httpMethod: "GET"
    uri: "/api/v2/pokemon?limit={limit}&offset={offset}"
    summary: "Gets the available Pokemons List. It's possible to define a limit and offset."
    parameters:
      limit:
        location: "query"
        description: "The number of Pokemons data to be retrieved."
        type: "integer"
        required: true
        default: 100
      offset:
        location: "query"
        description: "The offset."
        type: "integer"
        required: true
        default: 200
    responseModel: "PokemonsList"

models:
  PokemonsList:
    type: "array"
    location: "json"
    items:
      "$ref": "NamedAPIResourceList"

  NamedAPIResourceList:
    type: "object"
    location: "json"
    properties:
      count:
        location: "json"
        type: "integer"
      next:
        location: "json"
        type: "string"
      previous:
        location: "json"
        type: "string"
      results:
        location: "json"
        type: "array"
        items:
          "$ref": "DetailedResourceList"

  DetailedResourceList:
    type: "array"
    location: "json"
    properties:
      name:
        location: "json"
        type: "string"
      url:
        location: "json"
        type: "string"

pokeapi/src/Controller/PokeAPIController.php

<?php

namespace Drupal\pokeapi\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\http_client_manager\HttpClientInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Returns responses for PokeAPI routes.
 */
class PokeAPIController extends ControllerBase {

  /**
   * PokeAPI Http Client.
   *
   * @var \Drupal\http_client_manager\HttpClientInterface
   */
  protected $httpClient;

  /**
   * {@inheritdoc}
   */
  public function __construct(HttpClientInterface $http_client) {
    $this->httpClient = $http_client;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('pokeapi.http_client')
    );
  }

  /**
   * Get Client.
   *
   * @return \Drupal\http_client_manager\HttpClientInterface
   *   The Http Client instance.
   */
  public function getClient() {
    return $this->httpClient;
  }

  /**
   * Builds the response.
   */
  public function build() {

    $client = $this->getClient();
    $command = 'GetPokemonsList';

    $response = $client->call($command)->toArray();
    dpm($response);

    $build['content'] = [
      '#type' => 'item',
      '#markup' => $this->t('It works!'),
    ];

    return $build;
  }

}

result of dpm($response);

Array
(
    [0] => 1118
    [1] => https://pokeapi.co/api/v2/pokemon?offset=300&limit=100
    [2] => https://pokeapi.co/api/v2/pokemon?offset=100&limit=100
    [3] => Array
        (
        )

)

here array value indexed 3 in response should contain result array of the data.

I believe there is some error in the following definition in the posts.yml If anyone can point out the correct way it will be helpful.

      results:
        location: "json"
        type: "array"
        items:
          "$ref": "DetailedResourceList"

  DetailedResourceList:

Similar Question : How can I access nested data?

1

There is a small mistake in models structure, use below one will solve your issue

models:
  PokemonsList:
    type: "object"
    location: "json"
    properties:
      count:
        location: "json"
        type: "integer"
      next:
        location: "json"
        type: "string"
      previous:
        location: "json"
        type: "string"
      results:
        type: "array"
        location: "json"
        items:
          "$ref": "DetailedResourceList"

  DetailedResourceList:
    type: "object"
    location: "json"
    properties:
      name:
        location: "json"
        type: "string"
      url:
        location: "json"
        type: "string"
1

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.