Розширення

← Розширення

Ashterix

docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api

uk/docs/api/rest-bundle/developers/extensions.md новий файл +94 −0

Розширення

Що можна змінити або доповнити в REST Bundle без зміни його коду. Перелік інших пакетів екосистеми — на сторінці Розширення JsonRpcBundle.

RPC-події

REST-виклик генерує ті самі події, що й JSON-RPC (див. Життєвий цикл), тож лістенер застосунку працює для обох протоколів:

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Ufo\JsonRpcBundle\EventDrivenModel\Events\RpcEvent;
use Ufo\JsonRpcBundle\EventDrivenModel\Events\RpcPostResponseEvent;

#[AsEventListener(event: RpcEvent::POST_RESPONSE)]
final class AuditListener
{
    public function __invoke(RpcPostResponseEvent $event): void
    {
        // $event->rpcRequest->getMethod(), $event->response, $event->service
    }
}

Щоб відрізнити REST-виклик від JSON-RPC, перевірте carrier: RequestCarrier::getCarrier() instanceof Ufo\RestBundle\Services\RpcFromRest.

Заміна парсера запитів

Контролер залежить від Ufo\RestBundle\Interfaces\RestRequestParserInterface з одним методом parse(string $routeName, Request $request): Service. Успадкуйте RestRequestParser і задайте аліас інтерфейсу:

# config/services.yaml
Ufo\RestBundle\Interfaces\RestRequestParserInterface: '@App\Rest\TenantAwareParser'
use Symfony\Component\HttpFoundation\Request;
use Ufo\JsonRpcBundle\Server\ServiceMap\Service;
use Ufo\RestBundle\Services\RestRequestParser;

final class TenantAwareParser extends RestRequestParser
{
    public function parse(string $routeName, Request $request): Service
    {
        // наприклад, відхилити запит без заголовка tenant до виклику
        return parent::parse($routeName, $request);
    }
}

Парсер має залишити carrier у RequestCarrier: контролер виконує саме RequestCarrier::getCarrier(). Винятки, що реалізують Ufo\RestBundle\Exceptions\RestErrorInterface, повертаються зі статусом, що дорівнює їхньому коду; решта проходить через RestErrorNormalizer.

Читання REST-мапи

Ufo\RestBundle\Services\RestServiceMap повертає REST-маршрути й RPC-сервіси поточної групи API (з ApiGroupContext):

foreach ($restServiceMap->getVersions() as $version) {
    foreach ($restServiceMap->getRoutes($version) as $name => $route) {
        $service = $restServiceMap->getService($name, $version); // RPC Service
        // $route->getPath(), $route->getMethods()
    }
}

getRoute(), getService() і методи з невідомою версією кидають RestResourceNotFoundException.

Переклади з бандла

Бандл, що постачає RPC-методи, може постачати і їхні назви та описи; документи REST їх підхоплять (з 1.3):

public function prepend(ContainerBuilder $container): void
{
    $container->prependExtensionConfig('ufo_json_rpc', [
        'translations' => ['paths' => [__DIR__.'/../../translations']],
    ]);
}

Інший адаптер поруч із REST

Адаптер, що імпортує власний файл маршрутів для кожної групи API, реалізує Ufo\JsonRpcBundle\Routing\IApiRouteImport (автоконфігурація, тег ufo.rpc.route_import) — так само, як RestRouteImport:

use Ufo\JsonRpcBundle\Routing\IApiRouteImport;

final class AcmeRouteImport implements IApiRouteImport
{
    public function getResource(): string { return __DIR__.'/../../config/router.yaml'; }
    public function getRouteNamePrefixAttribute(): string { return '_acme_name_prefix'; }
}

Не успадковуйте для цього завантажувач маршрутів JsonRpcBundle. Мінімальний адаптер із RpcExecutor описано на сторінці Для розробників JsonRpcBundle.