Розширення
Що можна змінити або доповнити в 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.