RAML 1.0: обзор нововведений

RAML 1.0

О RAML — языке разметки, используемом для описания RESTful API, мы уже писали. В обсуждении статьи на Хабрахабре один из читателей заметил, что RAML уже давно не обновляется, чуть ли не с лета 2014 года.

Несколько месяцев формат RAML был существенно усовершенствован. Новая спецификация версии 1.0 была опубликована на официальном сайте относительно недавно, в начале октября 2015 года. По сравнению с предыдущей версией (0.8) в неё было внесено много изменений и дополнений. О наиболее значительных нововведениях мы подробно расскажем в этой статье.

Типы данных

Самая важная новация в RAML 1.0 — это поддержка типов данных. Теперь во вводной части документа можно очень подробно описывать все типы данных, с которыми работает API:

#%RAML 1.0 
title: New API
mediaType: application/json
types: 
  Person:
    type: object #
    properties:
      firstname: string
      lastname: string
      is_our_employee: boolean
 Document: 
    type: object
    properties: Author
     title: string
     signing_date: date

Типы данных, определённые в спецификации, можно использовать в дальнейшем при описании тел ответов, параметров URI, заголовков и query-парамертров, например:

/documents/{documentId}:
  get:
    responses:
      200:
        body:
          application/json:
            type: Document
  

Примеры: расширенные возможности

В документации к любому API желательно приводить как можно больше примеров.
В RAML 1.0 примеры можно добавлять в любую часть документа. Примеры могут представлены как в формате JSON, так и YAML:

#%RAML 1.0 
title: New API
mediaType: application/json
types: 
  Person:
    type: object #
    properties:
      firstname: string
      lastname: string
      is_our_employee: boolean
    examples:
      {
       firstname: Alexander
       lastname: Ivanov
       is_our_employee: true
       }

Благодаря примерам описание API становится более понятным и наглядным.

Аннотации

С помощью аннотаций в спецификации RAML можно вставлять дополнительные метаданные. Эта возможность полезна при проектировании API: в аннотации можно добавить информацию, которая окажется полезной в дальнейшем (для тестирования, дополнения документации и т.п.).
Рассмотрим простой пример (взят из официальной документации):

#%RAML 1.0
title: Illustrating annotations
mediaType: application/json
annotationTypes:
  experimental:
/groups:
  (experimental):

Во вводной части документа (атрибут annotationTypes) описывается общий формат аннотаций. Далее один из эндпоинтов API помечен как экспериментальный.

Аннотации можно использовать и в более сложных ситуациях — например, для описания тест-кейсов:

#%RAML 1.0 
title: Testing annotations
mediaType: application/json
annotationTypes:
  testCase:
    allowedTargets: [ Method ]
    allowMultiple: true
    usage: |
      Use this annotation to declare a test case.
      You may apply this annotation multiple times per location.
    properties:
      scenario: string
      setupScript?: string[]
      testScript: string[]
      expectedOutput?: string
/documents:
  type: myResourceTypes.collection
  get:
    (testCase):
      scenario: No Documents
      setupScript: deleteAllDocuments
      testScript: getAllDocuments
      expectedOutput: [ ]
    (testCase):
      scenario: One Document
      setupScript: [ deleteAllDocuments, addDocs ]
      testScript: getAllDocuments
      expectedOutput: '[ { "id": 999, "author": "John Smith" } ]'
    (testCase):
      scenario: Multiple Documents
      setupScript: [ deleteAllDocuments, addDocs ]
      testScript: getAllDocuments
      expectedOutput: '[ { "id": 998, "author": "Bob Brown" }, { "id": 999, "name": "John Smith" } ]'
   

Библиотеки

Ещё одно нововведение RAML 1.0 — библиотеки. Библиотекой называется файл, в который вынесены профили, типы данных и другая информация, помещаемая во вводную часть документа. Теперь в новом документе можно не расписывать подробно вводную часть, а сослаться на уже имеющиеся библиотеки. Такая практика напоминает подключение внешних библиотек и модулей в программном коде.
Приведём пример библиотеки:

#%RAML 1.0 Library
# Этот файл хранится в libraries/files.raml 
usage: |
  Use to define some basic file-related constructs.
types:
  File:
    properties:
      name:
        type: string
      length:
        type: integer
traits:
  drm:
    headers:
      drm-key:
resourceTypes:
  file:
    get:
      is: drm
    put:
      is: drm

После того, как библиотека сохранена в отдельном файле, к ней можно обращаться в основном файле спецификации:

#%RAML 1.0 
title: Files API
uses:
  files: !include libraries/files.raml
resourceTypes:
  file: !include files-resource.raml
/files:
  type: file

Надстройки и расширения

Надстройки (overlays) и расширения (extensions) предназначены для кастомизации описаний API — например, когда требуется создать (и затем регулярно обновлять и поддерживать) документацию к API на нескольких языках. Задача эта не так проста, как может показаться на первый взгляд. Большинство имеющихся инструментов для документирования API не могут справиться с этой задачей без дополнительных «костылей».

В RAML 1.0 с помощью надстроек можно без проблем реализовать поддержку многоязычной документации. Представим, что у нас имеется документация к API на английском языке, и нам нужно сделать для неё французскую локализацию. Английская документация хранится в файле booklibrary.raml. Приведём небольшой фрагмент:

#%RAML 1.0

title: Book Library API
documentation: 
-  title: Introduction
   content: automated access to the books
-  title: Licensing
   content: Please respect the copyright on this book

Чтобы добавить французскую локализацию, создадим файл-надстройку (overlay):

 #%RAML 1.0 Overlay
usage: French localisation
masterRef: booklibrary.raml
documentation: 
-  title: Introduction
   content: l’accès automatisé aux livres
-  title: licenсe
   content: Respectez les droits d’auteur s.v.p.

Этот файл включает только французские переводы; все описания методов и ответов при генерации будут взяты из основного файла.

C помощью расширений (extensions) можно создавать дополнительные описания методов и ответов. Это может понадобиться для адаптации описания API для разных категорий пользователей или для разных вариантов использования (например, в ситуации, когда пользователям бесплатной версии сервиса доступен базовый, а пользователям платной версии — расширенный набор функций),

Рассмотрим следующие фрагменты (примеры взяты отсюда):

Основной файл

#%RAML 1.0
title: Book Library API
documentation:
  - title: Introduction
    content: Automated access to books
  - title: Licensing
    content: Please respect copyrights on our books.
/books:
  description: The collection of library books
  get:

Расширение с описанием функциональности API для пользователей с правами администратора

#%RAML 1.0 Extension
usage: Add administrative functionality
masterRef: librarybooks.raml
/books:
  post:
    description: Add a new book to the collection

Расширение для кастомной версии API, доступной по указанному URL

#%RAML 1.0 Extension
usage: The location of the public instance of the Piedmont library API
masterRef: librarybooks.raml
baseUri: http://api.piedmont-library.com

Заключение

Рассмотренные нами нововведения свидетельствуют о том, что RAML развивается в сторону простого, но в то же время очень гибкого языка описания, позволяющего документировать даже самые сложные API.

Радует и то, что сейчас появляются и новые, более совершенные инструменты для создания документации для API. Осенью 2015 года компания MuleSoft (основной разработчик RAML) выпустила плагин API WorkBench (см. также репозиторий на GitHub) для текстового редактора Atom — рекомендуем обратим внимание. Будем надеяться, что в дальнейшем этот инструмент будет успешно развиваться.

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

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

© Habrahabr.ru