Symfony에서 Service에 Factory Method에서 생성한 객체를 주입

「Service에 Factory Method로 생성한 오브젝트 찔러도 좋다―」라고 조사하면 할 수 있었으므로 메모.
예를 들어 Guzzle을 사용하여 Qiita의 프로필 획득 API에 액세스하여 얻은 사용자 프로필을 표시하는 것을 만들었습니다.

우선은 Factory를 만든다.



Guzzle의 Client를 생성하는 Factory를 만듭니다.

src/Factory/HttpClientFactory
<?php

namespace App\Factory;

use GuzzleHttp\Client;

class HttpClientFactory
{
    public static function create($baseUri)
    {
        $httpClient = new Client(['base_uri' => $baseUri, 'timeout' => 2]);
        return $httpClient;
    }
}
HttpClientFactory::create('http://localhost:8080'); 와 같은 형태로 base_uri를 지정한 Client 객체를 돌려줍니다.

서비스 만들기



Qiita에서 지정한 사용자 ID의 프로필을 검색하는 서비스를 만듭니다.

src/Service/QiitaService.php
<?php

namespace App\Service;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

class QiitaService
{
    private $client;
    public function __construct(Client $client)
    {
        $this->client = $client;
    }

    public function getUser($userId)
    {
        try {
            $response = $this->client->get('api/v2/users/' . $userId);
            return json_decode((string) $response->getBody(), true);
        } catch (ClientException $e) {
            return null;
        }
    }
}

생성자에서 Client 객체를 인수로 사용합니다. 이 객체를 이용해 Qiita의 API에 액세스합니다만, get()로 호출하고 있는 URI는 Client 객체에 base_uri가 지정되어 있지 않으면 올바르게 동작하지 않습니다. 이제 이 서비스에 Factory에서 생성한 Client 객체를 주입해 봅시다.

서비스 컨테이너 설정하기



Service Container를 설정하여 Service에 Client 개체를 주입합니다.

config/services.yaml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones
+
+    qiitaClient:
+        class: GuzzleHttp\Client
+        factory: ['App\Factory\HttpClientFactory', 'create']
+        arguments:
+            $baseUri: 'https://qiita.com'
+
+    App\Service\QiitaService:
+        arguments:
+            $client: '@qiitaClient'

먼저 qiitaClient에서 Qiita용 Client를 생성하는 설정을 합니다. factory: ['App\Factory\HttpClientFactory', 'create'] 를 지정하면 HttpClientFactory의 create() 메서드를 호출합니다. arguments 에는 create() 메소드의 인수를 지정합니다. 여기서 https://qiita.com 를 지정하여 Qiita용 Client 객체를 생성할 수 있습니다.

그런 다음 QiitaService의 arguments에 @qiitaClient을 지정하여 Qiita 용 Client 객체를 주입합니다. 이것으로 완성입니다. Saigo가 Controller에서이 서비스를 사용하여 프로필을 볼 수 있습니다.

컨트롤러에서 서비스 사용



Controller에는 autowiring으로 Service가 주입되기 때문에, 이런 느낌으로 OK.

src/Controller/UserController.php
<?php

namespace App\Controller;

use App\Service\QiitaService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class UserController extends AbstractController
{
    /** @var QiitaService  */
    private $qiitaService;

    public function __construct(QiitaService $qiitaService)
    {
        $this->qiitaService = $qiitaService;
    }

    /**
     * @param $userId
     * @return Response
     * @Route("/user/{userId}", name="user")
     */
    public function index($userId)
    {
        $user = $this->qiitaService->getUser($userId);
        return $this->render('user/index.html.twig', ['user' => $user]);
    }
}

그리고 실행한 결과가 이쪽.

http://localhost:8000/user/ippey_s


일괄 Qiita에서 프로필 정보를 얻을 수있었습니다!

이번 샘플은 이쪽에 공개하고 있습니다.
htps : // 기주 b. 코 m / ぺ y / fu c와 ry-jin c chion-st

좋은 웹페이지 즐겨찾기