Пишем документацию API при помощи RAML

от автора

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 Designer

В правой части страницы автоматически генерируется интерактивная документация. Здесь же можно и протестировать API: для этого достаточно просто развернуть описание нужного запроса и нажать на кнопку Try it.

API Designer позволяет также загружать RAML-файлы с локальной машины. Поддерживается импорт файлов описаний API для Swagger.
Кроме того, API Designer хранит статистику тестовыx запросов к API.

API console

API console — полезный инструмент, разработанный всё той же компанией MuleSoft. С его помощью можно прямо в браузере генерировать документацию к API. Файлы спецификаций можно как загрузить с локальной машины, так и указать ссылку на внешний источник:

API Console

В состав API Console входит несколько файлов-образцов, представляющих собой описания API популярных веб-сервисов: Twitter, Instagram, Box.Com, LinkedIn. Мы попробовали сгенерировать на основе одного из низ документацию — выглядит вполне симпатично:

API Console

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

Заключение

В этой статье мы рассмотрели основные возможности RAML. Его несомненными преимуществами являются простота и логичность. Надеемся, что в скором будущем RAML получить ещё более широкое распространение и займёт достойное место в ряду инструментов для документирования API.
Если у вас есть вопросы — добро пожаловать в комментарии. Будем также рады, если вы поделитесь собственным опытом использования RAML на практике.

Если вы по тем или иным причинам не может оставлять комментарии здесь — добро пожаловать в наш блог.

Как вы описываете документацию API?

Никто ещё не голосовал. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

ссылка на оригинал статьи http://habrahabr.ru/post/265337/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *