Во время работы над проектомбудь то хайповые микросервисы или монолит) довольно часто бывает, что сервису необходимо определить задачу для другого сервиса. Задача достаточно тривиальна, если с обеих сторон используется одна и та же рама. Но все становится намного интереснее, когда на стороне подписчика мы авторизуем Laravel с его форматом по умолчанию, а на стороне редактора что-то модное в Go.

Пример формата Laravel по умолчанию
{
  "uuid": "59f3007b-e63c-4c71-b298-885563664cd6",
  "displayName": "App\\Jobs\\ProcessPodcast",
  "job": "Illuminate\\Queue\\CallQueuedHandler@call",
  "maxTries": null,
  "maxExceptions": null,
  "failOnTimeout": false,
  "backoff": null,
  "timeout": null,
  "retryUntil": null,
  "data": {
    "commandName": "App\\Jobs\\ProcessPodcast",
    "command": "O:23:\"App\\Jobs\\ProcessPodcast\":1:{s:11:\"stringParam\";s:12:\"abcdef012345\";}"
  }
}

Довольно странно перекладывать обучение такой полезной нагрузки на другую команду разработчиков. Среди явных недостатков можно выделить не только жесткую привязку в формате Laravel, но и явное перечисление задействованных классов. Поэтому мы рассматриваем следующее решение, которое первым придет в голову: собственный менеджер, которого мы научим понимать тот формат, о котором договариваемся.

Предположим, мы можем договориться о чем-то вроде этого
{
  "uuid": "59f3007b-e63c-4c71-b298-885563664cd3",
  "job": "EXAMPLE",
  "data": {
    "type": "TYPE_TEST",
    "params": {
      "stringParam": "tabcdef012345"
    }
  }
}

Но, чтобы не копаться в программировании, изобретать очередную байку, попробуем воспользоваться инструментами сервисного контейнера.

жидкость

Думаю, что с этим свойством все понятно и без объяснений. Поэтому идем дальше.

работа

В данном случае мы замаскировали Выделите \\Queue\\CallQueuedHandler@call ниже ПРИМЕР. В сервисном контейнере недостаточно просто указать ПРИМЕР как синоним класса Осветить\Очередь\CallQueuedHandlerпотому что Laravel при обработке очереди попытается вызвать метод огонь, если явно не указано иное. Поэтому мы просто наследуем и расширяем базовый класс нужным методом.

<?php

declare(strict_types=1);

namespace App\Providers;

use App\QueueHandler;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public $bindings = [
        // app()->bind(QueueHandler::NAME, QueueHandler::class);
        QueueHandler::NAME => QueueHandler::class
    ];
}
<?php

declare(strict_types=1);

namespace App;

use Illuminate\Contracts\Queue\Job;
use Illuminate\Queue\CallQueuedHandler;

class QueueHandler extends CallQueuedHandler
{
    public const NAME = 'EXAMPLE';
    public const JOB_CLASS = 'type';
    public const JOB_PARAMS = 'params';

    public function fire(Job $job, array $data): void {
        $this->call($job, $data);
    }

    protected function getCommand(array $data)
    {
        return $this->container->make(
            $data[self::JOB_CLASS],
            is_array($data[self::JOB_PARAMS] ?? null) ? $data[self::JOB_PARAMS] : []
        );
    }
}

данные

выше класса QueueHandler мы также заменили метод получитькомандувзять на себя решение задачи. Осталось дело для самых маленьких — связать TYPE_TEST с нашей работой Приложение\Задания\ProcessPodcast через поставщика услуг.

<?php

app()->bind('TYPE_TEST', \App\Jobs\ProcessPodcast::class);

Заключение

В результате мы получаем достаточно гибкий формат, который легко воспринимается сторонними разработчиками.

ЧИТАТЬ   BenQ представила игровой проектор 4K с Android TV и яркостью 2000 люмен

Простая настройка на стороне Laravel без изменения кода других сервисов.

Уменьшите объем данных, передаваемых по сети.

Source

От admin