Пишем документацию API при помощи RAML
Удобство работы с любым API во многом зависит от того, как написана и оформлена его документация. Cейчас мы ведём работу по стандартизации и унификации описания всех наших API, и вопросы документирования для нас особенно актуальны.
После долгих поисков мы решили оформлять документацию в формате RAML. Так называется специализированный язык для описания REST API. О его возможностях и преимуществах мы расскажем в этой статье.
Почему RAML
Как нужно документировать API? Вопрос этот не так прост, как может показаться на первый взгляд.
Первый и самый простой вариант, который приходит на ум — представить описание к API в виде обычного текстового документа. Так делают очень многие (в том числе и очень известные компании). Мы тоже не раз пользовались этим способом. При всей своей простоте он обладает следующими недостатками:
- текстовую документацию сложно поддерживать в актуальном состоянии;
- зачастую словесные описания API оказываются недостаточно наглядными;
- сфера использования «словесной» документации очень ограничена (например, на её основе нельзя сгенерировать интерактивную тестовую страницу).
Чтобы упростить процесс документирования, можно использовать специализированные инструменты и сервисы. Как правило, они генерируют документацию на основе описания в некотором стандартизованном формате — обычно это JSON или Markdown.
Ни один из этих форматов для написания документации не подходит. JSОN был изначально создан для обмена данными в вебе. При использовании его для других целей поневоле приходится прибегать к помощи «костылей» — например, кастомных полей, начинающихся со знака $. Кроме того, составлять описания в формате JSON вручную — дело достаточно рутинное и утомительное (в особенности если речь идёт об описаниях большого размера).
На описанные выше трудности обращали внимание многие пользователи популярного инструмента Swagger. Вскоре разработчики Swagger решили упростить работу по написанию спецификаций и создали фирменный редактор с поддержкой формата YAML.
Конечно, YAML гораздо удобнее, чем JSON. Но и его использование сопряжено с определёнными трудностями. Дело в том, что в описаниях API всегда имеются повторяющиеся элементы (например, схема ответа, которая может быть одинаковой для разных типов HTTP-запросов), которые приходится всякий раз прописывать вручную. Вот если бы можно их было раз и навсегда прописать в отдельном файле и ссылаться на него в случае небходимости… Но, увы, пока что такой возможности нет.
Что касается формата Markdown (он используется, например, в API BluePrint), то предназначен в первую очередь для оформления текста, а не для использования в качестве основы для генерирования. Приспособить его под документирование API очень сложно. По этой же причине не привели к каким-либо заметным результатам попытки cоздать формат описания API на базе XML — например, язык WADL (Web Application Desription Language), разработанный компанией Sun Microsystems ещё в 2009 году, но так и не получивший широкого распространения.
Создатели проекта RAML (эта аббревиатура означает RESTful API Modeling Language — язык для моделирования REST API) предприняли попытку разработать язык, предназначенный исключительно для описания API и исправить недочёты, свойственные другим форматам. Первая версия спецификации RAML была опубликована в 2013 году. Основным разработчиком RAML является компания MuleSoft; в проекте также принимают участие представители таких известных компаний, как Cisco, PayPal, ВoxInc. и других.
Несомненными преимуществами RAML являются:
- простой и логичный синтаксис, основанный на формате YAML;
- поддержка наследования и возможность подключения внешних файлов спецификаций.
Дополнительным плюсом является наличие большого количества конвертеров, парсеров и генераторов интерактивной документации. О некоторых из них мы расскажем ниже, а пока перейдём к обзору особенностей синтаксиса RAML.
Краткое введение в RAML
Структура документа
Файл спецификаций на RAML состоит из следующих структурных элементов:
- вводная часть («шапка»);
- схема безопасности;
- описание профилей;
- описание объектов и методов;
- описание ответов.
Рассмотрим эти элементы подробнее.
Вводная часть
Каждый документ на RAML начинается с вводной части, которая включает четыре обязательных элемента:
- версия RAML;
- имя документа;
- URI, по которому доступен API;
- версия API, описываемая в документации.
Выглядит это так:
#% RAML 0.8 title: Example API baseUri: http://api.example.com/{version} version: v1
Вводная часть может также включать различную дополнительную информацию — например, сведения об используемом протоколе для связи с API:
protocols: [http, https]
Можно во вводной части прописать и метаданные файла документации:
documentation - title: Home content: | API Test Documentation
Схемы безопасности
Чтобы начать работать с любым API, нужно пройти процедуру авторизации. Она может осуществляться разными способами: через OAuth, с помощью токенов, либо посредством простой HTTP-аутентификации. Для описания этой процедуры в RAML используются схемы безопасности (security schemes).
Рассмотрим в качестве примера, как описывается авторизация с использованием протокола OAuth2:
#%RAML 0.8 title: Example API version: 1 baseUri: https://api.example.com/{version} securedBy: [oauth_2_0] securitySchemes: - oauth_2_0: type: OAuth 2.0 describedBy: headers: Authorization: type: string queryParameters: access_token: type: string responses: 401: description: | Bad or expired token. 403: description: | Bad OAuth request settings: authorizationUri: https://example.com/oauth/authorize accessTokenUri: https://example.com/oauth/token authorizationGrants: [ code, token ]
Приведённый фрагмент содержит следующую информацию:
- в параметре type указывается, что в API используется авторизация по протоколу OAuth2;
- далее указывается, что авторизационные данные можно передавать либо в заголовке Authorization, либо в query-параметре access_token;
- после этого следуют возможные коды ответов и их описания;
- в конце раздела, в секции settings указываются URL для авторизации, URL для получения токена, а также необходимые для аутентификации параметры (authorization grants).
Для удобства схемы безопасности можно сохранять в отдельных файлах .raml или .yml, и затем обращаться к ним в случае необходимости:
#%RAML 0.8 title: Example API version: 1 baseUri: https://api.example.com/{version} securedBy: [oauth_2_0] securitySchemes: - oauth_2_0: !include oauth_2_0.yml
Это помогает ускорить процесс документирования, избежать лишних повторений и сделать документацию менее громоздкой.
Почитать более подробно о схемах безопасности и ознакомиться с конкретными примерами можно здесь (раздел Security).
Объекты и методы
Далее перечисляются основные объекты и пути к ним, а также HTTP-методы, которые используются с этими объектами:
/document get: put: post: /{documentId} get: delete:
В приведённом примере описывается API, с помощью которого можно работать с документами. Мы можем скачивать документы на локальную машину (GET), изменять cуществующие документы (PUT) и загружать новые (POST). С каждым отдельным документом ({documentId}) мы можем также выполнять следующие операции: загрузка на локальную машину (GET) и удаление (DELETE).
HTTP-заголовки, используемые с тем или иным методом, описываются при помощи свойства headers, например:
/documents get headers: X-Auth-Token: required: true
Обратите внимание на свойство required: оно указывает, является ли заголовок обязательным (true) или необязательным (false).
В описании объектов и методов могут использоваться многочисленные дополнительные параметры. Рассмотрим следующий пример:
/document /{documentId} uriParameters: id: description: document identification number type: string pattern: ^[a-zA-Z]{2}\-[0-9a-zA-Z]{3}\-\d{2}\-\d{5}$
Здесь мы указываем, что каждый из документов, доступ к которым можно получить через API, имеет собственный идентификационный код в виде строки (type: string), а также описываем формат этого кода с помощью регулярных выражений.
Свойства description, type и pattern можно использовать и в описаниях методов, например:
/documents get: description: Retrieve a list of documents post: description: Add a new document body: application/x-www-form-urlencoded formParameters: id: description: document identification number type: string pattern: [a-zA-Z]{2}\-[0-9a-zA-Z]{3}\-\d{2}\-\d{5}$ name: description: the name of the document type: string required: true author: description: The name of the author type: string required: true
В описании метода POST мы указываем параметры, которые нужно передать в теле запроса для добавления нового документа: ID, имя и имя автора. Каждый из этих параметров является строкой (type: string). Обратите внимание на свойство required: оно указывает, является ли параметр обязательным (true) или необязательным (false).
Для каждого метода можно прописать индивидуальную схему безопасности:
/documents get [securedBy: oauth_2_0]
Query-параметры
Для каждого метода в документации можно указать query-параметры, которые будут использоваться в запросе. Для каждого query-параметра указываются следующие характеристики: имя, тип, описание и пример:
/document: get: queryParameters: author: displayName: Author type: string description: The author's full name example: Ivan Petrov required: false name: displayName: Document Name type: string description: The name of the document example: Delivery contract required: false signingDate: displayName: signingDate type: date description: The date when the document was signed example: 2015-07-15 required: false
Профили
Чтобы избежать лишних повторений в описаниях, в RAML используются профили (traits), которые прописываются во вводной части документа:
#% RAML 0.8 title: Example API baseUri: http://api.example.com/{version} version: v1 traits: - searchable: queryParameters: author: displayName: Author type: string description: The author's full name example: Ivan Petrov required: false name: displayName: Document Name type: string description: The name of the document example: Delivery contract required: false signingDate: displayName: signingDate type: date description: The date when the document was signed example: 2015-07-15 required: false
В дальнейшем к профилю можно обращаться при описании любых методов:
/document: get: is: [searchable]
Более подробно о профилях и особенностях их использования можно почитать в официальной документации (раздел Traits).
Описание ответа
В описании ответа обязательно указывается его код. Также в описание можно добавить схему (schema) — перечисление входящих в ответ параметров и их типов. Можно также привести пример конкретного ответа (example).
/documents: /{documentId}: get: description: Retrieve document information responses: 200: body: application/json: schema | {"$schema": "http://json-schema.org/schema”, "type":"object" "description": "a document" "properties": { "id":{"type":"string"} "name":{"type":"string"} "author":{"type":"string"} "signingDate": {"type":"date"} example: | {"data:" { "id": "DOC3456" "name": "New Delivery Contract" "author": "Ivan Petrov" "signingDate": "2015-05-20" }, "success": true "status": 200 }
Cхемы ответов можно сохранять в отдельных файлах формата .yml или .raml и обращаться к ним в других частях документации:
schemas: - !include document-schema.yaml /articles: get: responses: 200: body: application/json: schema: document
Визуализация и генерация документации
RAML2HTML и другие конвертеры
Несмотря на то, что RAML — формат относительно новый, для него уже разработано достаточное количество конвертеров и парсеров. В качестве примера можно привести ram2htmtl, генерирующий на основе описания в формате RAML статическую HTML-страницу.
Устанавливается он при помощи менеджера пакетов npm:
$ npm -i g raml2html
Чтобы сконвертировать RAML-файл в HTML, достаточно выполнить простую команду:
$ raml2html api.raml > index.html
Поддерживается возможность создания собственных шаблонов для HTML-файлов (подробнее об этом см. в документации на GitHub по ссылке выше).
Из других конвертеров рекомендуем также обратить внимание на RAML2Wiki и RAML2Swagger.
API Designer
Компания Mulesoft (один из активных участников проекта RAML) создала специальный онлайн-инструмент, с помощью которого можно упростить работу по написанию документации и последующему тестированию API. Называется он API Designer.
Чтобы начать им пользоваться, нужно сначала зарегистрироваться на сайте. После этого можно приступать к работе. API designer предоставляет, во-первых, удобный интерактивный редактор для написания документации онлайн, а во-вторых — платформу для тестирования.
Выглядит всё это так:
В правой части страницы автоматически генерируется интерактивная документация. Здесь же можно и протестировать API: для этого достаточно просто развернуть описание нужного запроса и нажать на кнопку Try it.
API Designer позволяет также загружать RAML-файлы с локальной машины. Поддерживается импорт файлов описаний API для Swagger.
Кроме того, API Designer хранит статистику тестовыx запросов к API.
API console
API console — полезный инструмент, разработанный всё той же компанией MuleSoft. С его помощью можно прямо в браузере генерировать документацию к API. Файлы спецификаций можно как загрузить с локальной машины, так и указать ссылку на внешний источник:
В состав API Console входит несколько файлов-образцов, представляющих собой описания API популярных веб-сервисов: Twitter, Instagram, Box.Com, LinkedIn. Мы попробовали сгенерировать на основе одного из низ документацию — выглядит вполне симпатично:
Документация, получаемая на выходе, является интерактивной: в ней можно не только прочитать описание API, но и выполнить тестовые запросы.
Заключение
В этой статье мы рассмотрели основные возможности RAML. Его несомненными преимуществами являются простота и логичность. Надеемся, что в скором будущем RAML получить ещё более широкое распространение и займёт достойное место в ряду инструментов для документирования API.
Если у вас есть вопросы — добро пожаловать в комментарии. Будем также рады, если вы поделитесь собственным опытом использования RAML на практике.
Если вы по тем или иным причинам не может оставлять комментарии здесь — добро пожаловать в наш блог.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.