Symfony — аннотация никогда не импортировалась

Я использую фреймворк Symfony и собираюсь добавить движок автоматической документации в RESTful API моего проекта.

После некоторых поисков я нашел движок apidoc (http://apidocjs.com/). Это работает довольно просто: вам нужно добавить несколько аннотаций для каждого контроллера RESTful API и сгенерировать документацию.

Пример аннотации:

/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId  User's ID received in authorization request
* @apiParam {String} sessionKey  Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses  The name of current dictionary
* @apiSuccess {String} itemId  Item id which used in requests
* @apiSuccess {String} itemName  Item name
*/

public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}

Как видите, аннотация для apidoc такая же, как и для маршрутизации в Symfony.

Кстати, в производственной среде это работает нормально, но в среде разработки я получаю исключение, как

[Semantical Error] The annotation "@apiName" in method AppBundle\Controller\Api\apiDictionaryController::dictionaryListAction() was never imported.

Есть ли способ исправить эту проблему и сказать Symfony, что аннотацию для apidoc следует игнорировать?

4

Решение

Вы можете использовать IgnoreAnnotation аннотация, чтобы сказать читателю аннотации Docrine, чтобы пропустить эту аннотацию в вашем контроллере. Для этого просто добавьте аннотацию добавить @IgnoreAnnotation("Annotation") к комментарию документа класса.

В вашем случае:

/**
* @IgnoreAnnotation("apiName")
* @IgnoreAnnotation("apiGroup")
* @IgnoreAnnotation("apiParam")
* @IgnoreAnnotation("apiSuccess")
*/
class ActionController extends Controller/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId  User's ID received in authorization request
* @apiParam {String} sessionKey  Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses  The name of current dictionary
* @apiSuccess {String} itemId  Item id which used in requests
* @apiSuccess {String} itemName  Item name
*/

public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}

Вы также можете рассмотреть возможность открытия PR для Доктрина / аннотаций Проект для включения этой аннотации по умолчанию пропускается как этот.

Надеюсь, это поможет.

1

Другие решения

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

Вы можете добавить в черный список дополнительные аннотации, посмотреть Doctrine docs — игнорирование пропущенных исключений:

use Doctrine\Common\Annotations\AnnotationReader;

AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiSuccess');

Я бы положил это в Приложение / autoload.php так как это глобальная настройка.

1

Аннотации читаются во время компиляции DI-контейнера, поэтому лучше игнорировать аннотации apidocs во время компиляции. проход компилятора.

Пример:

<?php
namespace YourBundle\DependencyInjection;

use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class IgnoreApiDocsAnnotationsPass implements CompilerPassInterface {
public function process(ContainerBuilder $container) {
AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiDefine');
AnnotationReader::addGlobalIgnoredName('apiDeprecated');
AnnotationReader::addGlobalIgnoredName('apiDescription');
AnnotationReader::addGlobalIgnoredName('apiError');
AnnotationReader::addGlobalIgnoredName('apiErrorExample');
AnnotationReader::addGlobalIgnoredName('apiExample');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiHeader');
AnnotationReader::addGlobalIgnoredName('apiHeaderExample');
AnnotationReader::addGlobalIgnoredName('apiIgnore');
AnnotationReader::addGlobalIgnoredName('apiName');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiParamExample');
AnnotationReader::addGlobalIgnoredName('apiPermission');
AnnotationReader::addGlobalIgnoredName('apiPrivate');
AnnotationReader::addGlobalIgnoredName('apiSampleRequest');
AnnotationReader::addGlobalIgnoredName('apiSuccess');
AnnotationReader::addGlobalIgnoredName('apiSuccessExample');
AnnotationReader::addGlobalIgnoredName('apiUse');
AnnotationReader::addGlobalIgnoredName('apiVersion');
}
}

Я получил полный список аннотаций от Apidoc Docs. Вам необходимо зарегистрировать проход компилятора в вашем пакете с

<?php
namespace YourBundle;

use YourBundle\DependencyInjection\IgnoreApiDocsAnnotationsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class YourBundle extends Bundle {
public function build(ContainerBuilder $container) {
parent::build($container);
$container->addCompilerPass(new IgnoreApiDocsAnnotationsPass());
}

}
1

Вы должны импортировать маршрут:

использовать Sensio \ Bundle \ FrameworkExtraBundle \ Configuration \ Route;

-1