Перед написанием стать попытался найти что-то подобное, и, возможно, в силу каких-то обстоятельств не нашел. Решил изложить свое видение данного вопроса.

Откуда взялась идея? За последние несколько лет я сменил 3-4 компании, в которых мне доставалась мягко говоря лапша, толстенные контроллеры и минимум аннотаций. С чем именно связать отсутствие аннотаций — сказать сложно, возможно, это банальная лень или не знание того, что аннотации позволяют описывать больше, чем просто входящие параметры для классов/методов. А когда это начинает касаться API-контроллеров, то тут вообще весело, прикрутить FosRestBundle не проблема (я сейчас про более ленивый вариант, чем написание всего и вся самому ручками, хотя, как показывает практика — бандл проще).

Так вот, о чем это я? Прикрутили бандл, описали (в лучшем случае) через ParameterFetcher входные параметры и правила. Вроде бы все готово и работает, запросы бегают, ответы летают. Но как быть когда нужна документация на АПИ, какие варианты я только не видел. Самый убийственный был текстовые файлики в папке Resource/doc — но хоть служили куда надо. Уверен что для большенства кто будет читать это статью а не закроют ее сразу же, многое будет и так известно, но я все же опишу.

Приведу все примеры с ссылками на где брать и скринами как работает.

Итак, сам бандл — тут.

Далее идет спойлер с установкой NelimoApiDocBundle.

click
Ставится как и все остальное очень легко и просто через Composer:

        require nelmio/api-doc-bundle
    

Далее все еще проще его в AppKernel.php

        public function registerBundles()
        {
        //...
            return array(
                // ...
                new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
            );
        }
    

Самое важное (ну, во всяком случае по отношению к статье), прописываем пути для самой генерилки:

        # app/config/routing.yml

        NelmioApiDocBundle:
            resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
            prefix:   /api/doc
    


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

Итак, у нас есть простой метод:

click
        public function getIndexAction(ParamFetcher $paramFetcher)
        {
            $view = View::create();

            $result = [
                'status' => 'success',
                'data' => [
                    'someKey' => 'SomeValue'
                ]
            ];
            $view->setData(['result' => $result]);
            return $view;
        }
    


Пока что этот метод ничем особенным не выделяется, и мы его чуть чуть расширим.

click
        /**
         * @Get(name="_additional_name_in_route", path="/")
         *
         * @Template(engine="twig", template="HabrApiDocBundle:Default:index.html.twig")
         *
         * @QueryParam(
         *      name="name",
         *      requirements="\w+",
         *      strict=true,
         *      nullable=false,
         *      description="Some description"
         * )
         *
         * @param ParamFetcher $paramFetcher
         * @return View
         */
        public function getIndexAction(ParamFetcher $paramFetcher)
        {
            $view = View::create();

            $result = [
                'status' => 'success',
                'data' => [
                    'someKey' => 'SomeValue'
                ]
            ];
            $view->setData(['result' => $result]);
            return $view;
        }
    


Теперь можно разобраться, что ж мы там написали такого:
  1. @Get — самый простой и быстрый способ переопределить урл роута для методов, которые отвечают только на 1 тип запроса (REST Full). Это даст нам возможность сделать postIndexAction deleteIndexAction — ну и так далее, суть поймана.
  2. @Templating — использовать или нет, тут уже по желанию. Я предпочту использовать, например, для стандартизации ответов.
  3. @QueryParam — первая плюшка, использование @QueryParam или @RequestParam соответственно позволит вам управлять входными данными. Например, у нас есть поле name, которое НЕ может быть пустым, должно соответствовать патерну \w+ и не менее главное — это Description, в котором можно написать, на кой оно надо взагали.

На этом вроде бы можно и закончить, описал плюшку и хватит, но ведь еще нужна документация на этот чудо метод, причем желательно информативно читабельная.

* @ApiDoc(
*      statusCodes={
*          200="Returned when successful",
*          403="Returned when the user is not authorized to say hello",
*          404={
*              "Returned when the user is not found",
*              "Returned when something else is not found"
*                },
*            },
*            description = "Add here some description for this method",
*           requirements = {
*                {"name"="name", "datatype"="string", "requirements"="\w+", "description" = "description for this parameter"}
*            },
*            cache=false,
*            tags = {
*                "stable" = "green",
*                "deprecated" = "#ff0000"
*            },
*            deprecated = true,
*            section = "First section"
*       )

Начну описывать по порядку:
  1. @ApiDoc() — естественно мы в начале укажем к испольлзованию сам бандл,
  2. statusCodes — назначение данного параметра видно из его названия, но он в итоге очень красиво выглядит в документации, расскажет нам, что и в каких случаях мы можем получить в качестве ответа.
  3. description — ну тоже как бы пришел капитан, с той лишь разницей, что теперь его будет видно в документации.
  4. requirements — сюда пишется массив Query/Request параметров с описанием их требований, что так же будет отображено в документации.
  5. tags — теги, это просто нечто. Когда можно на каждый метод поставить какой нибудь свой тег.
  6. deprecated — тоже приятная фича, когда можно помечать методы, которые планируется больше не использовать.
  7. section — одно из самых полезных дополнений, позволяет объединять в группы методы, даже если они находятся в разных классах.

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

ScreenShot
Результат сгенерированной доки


P.S> Поправил ссылку на скрин

Комментарии (0)