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’acces automatise 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, приглашаем поделиться опытом. Если вам кажется, что мы забыли рассказать о каком-то интересном нововведении — напишите нам, и мы обязательно добавим его в обзор.

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

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


  1. cleg
    07.04.2016 18:37
    +2

    RAML 1.0 предлагает, конечно, классные плюшки. И IDE поверх ATOM они напилили приличную весьма
    Но главная беда в том, что больше почти ни один инструмент 1.0 не поддерживает. Ни генераторы документации, ни даже web-консолька от самих Mulesoft (у них есть ветка, в которой они поддержку пилят, но она скорее сломана, чем жива)

    Поэтому на 1.0 пока можно только облизываться. Ну или начать его использовать в надежде что инструменты подтянутся. ATOM-ная IDE уже более-менее с 1.0 работает


    1. StepEv
      07.04.2016 21:09

      Да, я уже наступил на эти грабли. Ушёл переписывать в swagger


      1. roces
        07.04.2016 22:22

        Swagger как open source проект, к сожалению, имеет на удивление упёртых хозяев. Очень много пул-реквестов закрывается просто потому, что «это противоречит нашей идеологии и мы больше ничего не хотим слушать».


      1. cleg
        07.04.2016 22:40

        Swagger как-то на первый взгляд показался поскучней. У RAML это просто болезнь перехода с версии на версию…


        1. StepEv
          08.04.2016 06:46

          Так потому и начал писать на RAML 1.0, что «синтаксисический сахар» привлёк. И редактор в Atom удобный.

          Но толку то без возможности документацию сгенерировать.


      1. maximw
        08.04.2016 00:28

        Та же ситуация.
        Но после RAML Swagger кажется местами многословным, неудобным, нелогичным.
        Даже без генератора документации RAML читается гораздо лучше, чем Swagger.


        1. StepEv
          08.04.2016 06:48

          Всё же сгенерированная html документация получше читается

          Автор raml2html проект забросил и пока альтернатив не видать. Ждём энтузиастов.


          1. maximw
            08.04.2016 19:26

            Ну html это само собой лучше. Я говорил про сравнение голого yaml в Raml и в Swagger.


  1. webmoder
    07.04.2016 18:42

    Очень смутило:
    usage: |
    Use this annotation to declare a test case.
    You may apply this annotation multiple times per location.

    А почему необходимо придумывать языки для описания REST API?
    Разве с этим не справится JSON?
    Какие преимущества это дает?

    .З.Ы. в общем одни вопросы.


    1. cleg
      07.04.2016 22:40

      так они ничего не придумали, просто заюзали YAML. YAML чуть проще читается/пишется (сугубо на мой взгляд)


    1. StepEv
      08.04.2016 06:49
      +1

      JSON не для людей был придуман, а для машин. Читать его глазками то ещё «удовольствие». В отличие от YAML, который как раз задуман человеко-читаемым.


    1. AndreiYemelianov
      08.04.2016 10:02
      +1

      Любой инструмент должен использоваться сугубо по назначению. JSON был создан для обмена данными в вебе, а не для описания API — об этом здесь в комментариях уже писали. Поэтому при составлении документации к API поневоле приходится прибегать к помощи «костылей». Да и составлять в JSON длинные описания довольно утомительно… И не менее утомительно их читать (на это уже обратил внимание другой комментатор).


  1. kekekeks
    07.04.2016 18:56
    -1

    Дополнения и нововведения — это, конечно, хорошо, только без поддержки утилит типа мок-серверов и генераторов клиентского/серверного кода оно мало полезно.


  1. unpunk
    08.04.2016 14:27
    +5

    Насколько я понимаю, многие библиотеки не парсят RAML самостоятельно, а опираются на официальную библиотеку raml-js-parser. Эта библиотека предназначена для RAML 0.8, но так же может и худо-бедно понимать часть RAML 1.0 при отключенной валидации. Мало кто желает получить шквал багрепортов из-за нестабильного поведения.

    В свою очередь постепенно разрабатывается raml-js-parser-2, переходить на который здесь и сейчас проблематично[1] из-за несостыковок в API[2]. Я думаю что в целях экономии времени и сил — сообщество ожидает стабильной версии RAML 1.0.

    Тем временем, идет разработка RAML1.0 RC2[3] и авторы уже оптимистично предполагают, что от выхода RC2 до релиза не должно пройти много времени[4].

    Со своей стороны предполагаю что схемы версии 1.0 могут в организации жить до 5-10 лет, потому я не против того чтобы начать работать с текущим RC и ожидать новых инструментов в скором будущем.

    [1]: github.com/raml2html/raml2html/issues/156#issuecomment-159296208
    [2]: github.com/raml-org/raml-js-parser-2/issues/11
    [3]: github.com/raml-org/raml-spec/tree/raml-10-rc2
    [4]: raml.org/blogs/update-raml-10-current-status