Symfony 4 基本控制器 class 用于所有其他 API 控制器

Symfony 4 base controller class for all other API controllers

在我的 Symfony 4 应用程序中,我需要有多个控制器,每个控制器用于 mount/group 不同前缀中的各种 API 端点。

每个控制器都需要先初始化并在 class 属性 API 客户端中设置并设置凭据。为了避免所有代码重复,我想创建一个 BaseController,以便其他人可以扩展并直接访问或让客户端 属性 满足他的所有需求。

基地控制器:

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Vendor\ApiClient;

class BaseApiController extends Controller
{
    /**
     * @var ApiClient
     */
    protected $apiClient;

    public function __construct( array $apiClientCredentials, ApiClient $apiClient )
    {
        $this->apiClient = $apiClient;
        $this->apiClient->credentials($apiClientCredentials['id'], $apiClientCredentials['main_password']);
    }

}

我想让 API 属性 准备好成为 called/used:

的众多类似控制器之一
<?php
namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Account endpoints
 * @Route("/account")
 */
class AccountApiController extends BaseApiController
{

    /**
     * Get the balance.
     * @Route("/balance", name="balance")
     */
    public function balance()
    {
        return new JsonResponse($this->apiClient->getBalance());
    }
}

这就是我所拥有的,但仍然无法按预期工作,想知道如何将此设置放在一起的最佳做法是什么?

编辑:这是我收到的错误消息。

Cannot autowire service "App\Controller\AccountApiController": argument "$apiClientCredentials" of method "App\Controller\BaseApiController::__construct()" must have a type-hint or be given a value explicitly.

编辑:添加我的 services.yaml

# config/services.yaml
parameters:
    app.creds:
        id: '%env(ACCOUNT_ID)%'
        main_password: '%env(ACCOUNT_MAIN_PASSWORD)%'
# ...
services:
    _defaults:
        autowire: true
    # ...
    App\Controller\BaseApiController:
        arguments:
            $apiClientCredentials: '%app.creds%'

您的 APiClient 范围需要保护

/**
 * @var ApiClient
 */
protected $apiClient;

因为我要在多个控制器中使用它,所以现在看来​​只是绑定参数是公平的。

services:
    _defaults:
        autowire: true      
        autoconfigure: true 
        public: false      
        bind:
            $walletCreds: '%app.wallet_creds%'

此外,基础 class 必须是抽象的:

abstract class BaseApiController extends Controller
{
//...