Перед написанием стать попытался найти что-то подобное, и, возможно, в силу каких-то обстоятельств не нашел. Решил изложить свое видение данного вопроса.
Откуда взялась идея? За последние несколько лет я сменил 3-4 компании, в которых мне доставалась мягко говоря лапша, толстенные контроллеры и минимум аннотаций. С чем именно связать отсутствие аннотаций — сказать сложно, возможно, это банальная лень или не знание того, что аннотации позволяют описывать больше, чем просто входящие параметры для классов/методов. А когда это начинает касаться API-контроллеров, то тут вообще весело, прикрутить FosRestBundle не проблема (я сейчас про более ленивый вариант, чем написание всего и вся самому ручками, хотя, как показывает практика — бандл проще).
Так вот, о чем это я? Прикрутили бандл, описали (в лучшем случае) через ParameterFetcher входные параметры и правила. Вроде бы все готово и работает, запросы бегают, ответы летают. Но как быть когда нужна документация на АПИ, какие варианты я только не видел. Самый убийственный был текстовые файлики в папке Resource/doc — но хоть служили куда надо. Уверен что для большенства кто будет читать это статью а не закроют ее сразу же, многое будет и так известно, но я все же опишу.
Приведу все примеры с ссылками на где брать и скринами как работает.
Итак, сам бандл — тут.
Далее идет спойлер с установкой NelimoApiDocBundle.
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
Дальше я пробегусь чисто поверхностно по самым простым и основным моментам, оставив ваш пытливый ум читать и разбирать документацию, если такое желание возникнет.
Итак, у нас есть простой метод:
public function getIndexAction(ParamFetcher $paramFetcher) { $view = View::create(); $result = [ 'status' => 'success', 'data' => [ 'someKey' => 'SomeValue' ] ]; $view->setData(['result' => $result]); return $view; }
Пока что этот метод ничем особенным не выделяется, и мы его чуть чуть расширим.
/** * @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; }
Теперь можно разобраться, что ж мы там написали такого:
- @Get — самый простой и быстрый способ переопределить урл роута для методов, которые отвечают только на 1 тип запроса (REST Full). Это даст нам возможность сделать postIndexAction deleteIndexAction — ну и так далее, суть поймана.
- @Templating — использовать или нет, тут уже по желанию. Я предпочту использовать, например, для стандартизации ответов.
- @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" * )
Начну описывать по порядку:
- @ApiDoc() — естественно мы в начале укажем к испольлзованию сам бандл,
- statusCodes — назначение данного параметра видно из его названия, но он в итоге очень красиво выглядит в документации, расскажет нам, что и в каких случаях мы можем получить в качестве ответа.
- description — ну тоже как бы пришел капитан, с той лишь разницей, что теперь его будет видно в документации.
- requirements — сюда пишется массив Query/Request параметров с описанием их требований, что так же будет отображено в документации.
- tags — теги, это просто нечто. Когда можно на каждый метод поставить какой нибудь свой тег.
- deprecated — тоже приятная фича, когда можно помечать методы, которые планируется больше не использовать.
- section — одно из самых полезных дополнений, позволяет объединять в группы методы, даже если они находятся в разных классах.
Вот на этом, наверное, поверхностный обзор бандла я закончу, приведя в качестве пруфа скрин того, что получилось в результате:
![image](https://photos-3.dropbox.com/t/2/AACfh9GQ-X2axlypWB2QsPQgNKJU_n_DFmUXv_G1C-kuWg/12/82286434/png/32x32/1/1437141600/0/2/Screenshot%20from%202015-07-17%2014%3A39%3A17.png/COKunicgASACIAMgBCAFIAYgBygBKAI/YTHg9pDX6aqFhJWk79kyObIyWc27tzBwu-pW7Qz13Mw?size=1600x1200&size_mode=2)
ссылка на оригинал статьи http://habrahabr.ru/post/262927/
Добавить комментарий