0

As background, I am rebuilding some old code and want to wrap all the curl based requests in an interface (HttpRequestInterface) so I can swap that out later without having to write all the api calls right now.

I am trying to pass the HttpRequestInterface into controller, but it keeps saying `

TypeError: Argument 1 passed to Drupal\my_api\Controller\MyController::__construct() must be an instance of Drupal\my_api\Controller\HttpRequestInterface, instance of Drupal\my_api\Services\HttpRequest\CurlRequest given

I am new to Drupal from the .Net world and love how this functionality is out of the box and it seems like I am following the examples and code I find in core, but obviously I am missing something.

***One thing that sticks out is that this error message has the wrong namespace for HttpRequestInterface.

Below are the relevant files, I have only included what I think is pertinent to the issue, more can be made available.

Controller:

<?php

namespace Drupal\my_api\Controller;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Drupal\my_api\Controller\BaseApiController;

/**
 * Controller routines for Api routes.
 */
class RallyBoundController extends BaseApiController {

`BaseController:

namespace Drupal\my_api\Controller;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\my_api\Services\HttpRequest\HttpRequestInterace;

/**
 * BaseApiController abstracts away common api concerns.
 */
abstract class BaseApiController extends ControllerBase {
  protected $httpService;

  /**
   * Contructor requires HttpRequest Service.
   *
   * @param HttpRequestInterface $httpService
   *   Implementation of HttpRequestInterface defined in services.yml.
   */
  public function __construct(HttpRequestInterface $httpService) {
    $this->httpService = $httpService;
  }

  /**
   * Get the HttpRequest implemention as interface so we can swap out as needed.
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('my_api.httprequest')
    );
  }

Service.yml:

services:
  my_api.httprequest:
    class: Drupal\my_api\Services\HttpRequest\CurlRequest

HttpRequestInterface:

namespace Drupal\my_api\Services\HttpRequest;

/**
 * HttpRequestInterace defines interface for making Http GET Requests.
 */
interface HttpRequestInterface {

CurlRequest:

namespace Drupal\my_api\Services\HttpRequest;

use Drupal\my_api\Services\HttpRequest\HttpRequestInterface;

/**
 * HttpRequest Implementation of HttpRequestInterface using CURL.
 */
class CurlRequest implements HttpRequestInterface {

Thanks for the help.

5
  • Hmm... are you aware of Guzzle being available? Still looking at code. Are you using two different modules? One of the namespaces refers to mjff_api and others refer to my_api. – Kevin Dec 21 '18 at 4:35
  • I am a week into Drupal, never heard of guzzle, but will soon. – Rob Allen Dec 21 '18 at 4:36
  • although if I put guzzle behind an interface, I would still imagine the same error would happen – Rob Allen Dec 21 '18 at 4:38
  • Guzzle will likely simplify this for you, but I’ll provide answer anyway. It’s a great package for making http clients and many other features. Drupal has a service for it api.drupal.org/api/drupal/core%21core.services.yml/service/… – Kevin Dec 21 '18 at 4:38
  • Guzzle looks nice and easy btw. Going to go ahead a rewrite the old curl stuff – Rob Allen Dec 21 '18 at 4:53
1

In the BaseController file, you have a typo in the interface classname. Fix that and clear the cache. Your module namespace seems to be inconsistent too. Your custom classes should be namespaces under the same module name they are defined in.

use Drupal\my_api\Services\HttpRequest\HttpRequestInterace;

to

use Drupal\my_api\Services\HttpRequest\HttpRequestInterface;

PHP can’t figure out where the class is due to the typo, and expects it to be defined locally in the Controller class file, hence why your error message lists an incorrect namespace to the interface.

5
  • Kevin, can you look again. I was removing the mjff in favor of 'my' originally, but after adding new code I forgot – Rob Allen Dec 21 '18 at 4:40
  • That’s what I figured - but check the use statement in the BaseController for your interface - it has a typo. PHP won’t be able to find it and that’s why the error message is giving the wrong path for it. – Kevin Dec 21 '18 at 4:42
  • oh my, so bad. Thank you. Is there anyway for those types of errors to be more apparent? I'm like a week into php. – Rob Allen Dec 21 '18 at 4:44
  • Absolutely - my advice would be to get PHPStorm. It will be a great helping hand navigating new codebase. It would have color coded the line in a way you knew something was wrong about it. You’d also see that the IDE would not be able to hop to the class definition either which would certainly tell you something is amiss. The cherry on top is it will often autocomplete statements and add use lines automatically - it’s really awesome about that. You didn’t really do anything wrong with PHP, just a simple typo. – Kevin Dec 21 '18 at 4:45
  • There are some other IDEs too as well as VSCode but PHPStorm will be your best friend in this new environment. – Kevin Dec 21 '18 at 4:58

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