«1. Введение

В наших первых двух статьях о RAML — языке моделирования RESTful API — мы представили некоторый базовый синтаксис, включая использование типов данных и схемы JSON, и показали, как упростить определение RAML с помощью извлечение общих шаблонов в типы и характеристики ресурсов.

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

2. Наш API

В этой статье мы сосредоточимся на той части нашего API, которая включает в себя тип сущности под названием Foo.

Вот ресурсы, из которых состоит наш API:

    GET /api/v1/foos POST /api/v1/foos GET /api/v1/foos/{fooId} PUT /api/v1/foos/{fooId } DELETE /api/v1/foos/{fooId}

3. Включает

Целью включения является модульность значения сложного свойства в определении RAML путем помещения значения свойства во внешний файл.

Наша первая статья кратко касалась использования включений, когда мы задавали типы данных и примеры, свойства которых повторялись во всем API.

3.1. Общее использование и синтаксис

Тег !include принимает единственный аргумент: местоположение внешнего файла, содержащего значение свойства. Это местоположение может быть абсолютным URL-адресом, путем относительно корневого файла RAML или путем относительно файла включения.

Расположение, начинающееся с косой черты (/), указывает путь относительно расположения корневого файла RAML, а расположение, начинающееся без косой черты, интерпретируется как относительно расположения включающего файла.

Логическим следствием последнего является то, что включаемый файл может сам содержать другие директивы !include.

Вот пример, показывающий все три варианта использования тега !include:

#%RAML 1.0
title: Baeldung Foo REST Services API
...
types: !include /types/allDataTypes.raml
resourceTypes: !include allResourceTypes.raml
traits: !include http://foo.com/docs/allTraits.raml

3.2. Типизированные фрагменты

Вместо того, чтобы помещать все типы, типы ресурсов или черты в их собственные включаемые файлы, вы также можете использовать специальные типы включений, известные как типизированные фрагменты, чтобы разбить каждую из этих конструкций на несколько включаемых файлов, указав другой файл. для каждого типа, типа ресурса или характеристики.

Вы также можете использовать типизированные фрагменты для определения элементов пользовательской документации, именованных примеров, аннотаций, библиотек, наложений и расширений. Мы рассмотрим использование наложений и расширений позже в этой статье.

Хотя это и не требуется, первая строка включаемого файла, который является типизированным фрагментом, может быть идентификатором фрагмента RAML следующего формата:

#%RAML 1.0 <fragment-type>

Например, первая строка файла типизированного фрагмента для чертой будет:

#%RAML 1.0 Trait

Если используется идентификатор фрагмента, то содержимое файла ДОЛЖНО содержать только действительный RAML для указанного типа фрагмента.

Давайте сначала посмотрим на часть раздела свойств нашего API:

traits:
  - hasRequestItem:
      body:
        application/json:
          type: <<typeName>>
  - hasResponseItem:
      responses:
          200:
            body:
              application/json:
                type: <<typeName>>
                example: !include examples/<<typeName>>.json

Чтобы разделить этот раздел на модули с помощью типизированных фрагментов, мы сначала перепишем раздел свойств следующим образом:

traits:
  - hasRequestItem: !include traits/hasRequestItem.raml
  - hasResponseItem: !include traits/hasResponseItem.raml

Мы бы затем напишите файл типизированного фрагмента hasRequestItem.raml:

#%RAML 1.0 Trait
body:
  application/json:
    type: <<typeName>>

Файл типизированного фрагмента hasResponseItem.raml будет выглядеть следующим образом:

#%RAML 1.0 Trait
responses:
    200:
      body:
        application/json:
          type: <<typeName>>
          example: !include /examples/<<typeName>>.json

4. Библиотеки

Библиотеки RAML могут использоваться для модуляции любого числа и комбинация типов данных, схем безопасности, типов ресурсов, признаков и аннотаций.

4.1. Определение библиотеки

Хотя обычно библиотека определяется во внешнем файле, на который затем ссылаются как на включение, библиотека также может быть определена встроенной. Библиотека, содержащаяся во внешнем файле, также может ссылаться на другие библиотеки.

В отличие от обычного включаемого или типизированного фрагмента, библиотека, содержащаяся во внешнем файле, должна объявлять имена определяемых элементов верхнего уровня.

Давайте перепишем нашу секцию признаков в виде библиотечного файла:

#%RAML 1.0 Library
# This is the file /libraries/traits.raml
usage: This library defines some basic traits
traits:
  hasRequestItem:
    usage: Use this trait for resources whose request body is a single item
    body:
      application/json:
        type: <<typeName>>
  hasResponseItem:
    usage: Use this trait for resources whose response body is a single item
    responses:
        200:
          body:
            application/json:
              type: <<typeName>>
              example: !include /examples/<<typeName>>.json

4.2. Применение библиотеки

Библиотеки применяются с помощью свойства использования верхнего уровня, значением которого является один или несколько объектов, имена свойств которых являются именами библиотек, а значения свойств составляют содержимое библиотек.

«Как только мы создали библиотеки для наших схем безопасности, типов данных, типов ресурсов и трейтов, мы можем применить библиотеки к корневому файлу RAML:

#%RAML 1.0
title: Baeldung Foo REST Services API
uses:
  mySecuritySchemes: !include libraries/security.raml
  myDataTypes: !include libraries/dataTypes.raml
  myResourceTypes: !include libraries/resourceTypes.raml
  myTraits: !include libraries/traits.raml

4.3. Ссылка на библиотеку

Ссылка на библиотеку осуществляется путем объединения имени библиотеки, точки (.) и имени элемента (например, типа данных, типа ресурса, признака и т. д.), на который делается ссылка.

Вы можете вспомнить из нашей предыдущей статьи, как мы реорганизовали наши типы ресурсов, используя определенные признаки. В следующем примере показано, как переписать наш тип ресурса «item» в качестве библиотеки, как включить файл библиотеки признаков (показан выше) в новую библиотеку и как ссылаться на свойства, добавляя к именам свойств префикс с квалификатором имени библиотеки. («myTraits»):

#%RAML 1.0 Library
# This is the file /libraries/resourceTypes.raml
usage: This library defines the resource types for the API
uses:
  myTraits: !include traits.raml
resourceTypes:
  item:
    usage: Use this resourceType to represent any single item
    description: A single <<typeName>>
    get:
      description: Get a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasResponseItem, myTraits.hasNotFound ]
    put:
      description: Update a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasRequestItem, myTraits.hasResponseItem, myTraits.hasNotFound ]
    delete:
      description: Delete a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasNotFound ]
      responses:
        204:

5. Наложения и расширения

Наложения и расширения — это модули, определенные во внешних файлах, которые используются для расширения API. Наложение используется для расширения неповеденческих аспектов API, таких как описания, инструкции по использованию и элементы пользовательской документации, тогда как расширение используется для расширения или переопределения поведенческих аспектов API.

В отличие от включений, на которые ссылаются другие файлы RAML для применения, как если бы они были встроены в код, все файлы наложений и расширений должны содержать ссылку (через свойство masterRef верхнего уровня) на свой главный файл, который может быть либо допустимое определение API RAML, либо другой файл наложения или расширения, к которому они должны быть применены.

5.1. Определение

Первая строка файла оверлея или расширения должна быть отформатирована следующим образом:

RAML 1.0 Overlay

И первая строка файла оверлея должна быть отформатирована аналогично:

RAML 1.0 Extension

5.2. Ограничения использования

При использовании набора наложений и/или расширений все они должны ссылаться на один и тот же основной файл RAML. Кроме того, инструменты обработки RAML обычно ожидают, что корневой файл RAML и все файлы наложений и расширений будут иметь общее расширение файла (например, «.raml»).

5.3. Сценарии использования наложений

Мотивация наложений заключается в том, чтобы предоставить механизм для отделения интерфейса от реализации, что позволяет более ориентированным на человека частям определения RAML изменяться или расширяться чаще, в то время как основные поведенческие аспекты API остаются неизменными. стабильный.

Обычный пример использования оверлеев — предоставление пользовательской документации и других описательных элементов на нескольких языках. Давайте перепишем название нашего API и добавим некоторые элементы пользовательской документации:

#%RAML 1.0
title: API for REST Services used in the RAML tutorials on Baeldung.com
documentation:
  - title: Overview
  - content: |
      This document defines the interface for the REST services
      used in the popular RAML Tutorial series at Baeldung.com.
  - title: Copyright
  - content: Copyright 2016 by Baeldung.com. All rights reserved.

Вот как мы бы определили оверлей на испанском языке для этого раздела:

#%RAML 1.0 Overlay
# File located at (archivo situado en):
# /overlays/es_ES/documentationItems.raml
masterRef: /api.raml
usage: |
  To provide user documentation and other descriptive text in Spanish
  (Para proporcionar la documentación del usuario y otro texto descriptivo
  en español)
title: |
  API para servicios REST utilizados en los tutoriales RAML
  en Baeldung.com
documentation:
  - title: Descripción general
  - content: |
      Este documento define la interfaz para los servicios REST
      utilizados en la popular serie de RAML Tutorial en Baeldung.com.
  - title: Derechos de autor
  - content: |
      Derechos de autor 2016 por Baeldung.com.
      Todos los derechos reservados.

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

5.4. Варианты использования расширений

Как вы можете догадаться из названия, расширения используются для расширения API путем добавления новых вариантов поведения и/или изменения существующих вариантов поведения API. Аналогией из мира объектно-ориентированного программирования может быть подкласс, расширяющий суперкласс, где подкласс может добавлять новые методы и/или переопределять существующие методы. Расширение также может расширять нефункциональные аспекты API.

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

Ниже приведено расширение, которое переопределяет версию нашего API и добавляет ресурсы, недоступные в предыдущей версии:

#%RAML 1.0 Extension
# File located at:
# /extensions/en_US/additionalResources.raml
masterRef: /api.raml
usage: This extension defines additional resources for version 2 of the API.
version: v2
/foos:
  /bar/{barId}:
    get:
      description: |
        Get the foo that is related to the bar having barId = {barId}
      typeName: Foo
      queryParameters:
        barId?: integer
        typeName: Foo
        is: [ hasResponseItem ]

А вот оверлей на испанском языке для этого расширения:

#%RAML 1.0 Overlay
# Archivo situado en:
# /overlays/es_ES/additionalResources.raml
masterRef: /api.raml
usage: |
  Se trata de un español demasiado que describe los recursos adicionales
  para la versión 2 del API.
version: v2
/foos:
  /bar/{barId}:
    get:
      description: |
        Obtener el foo que se relaciona con el bar tomando barId = {barId}

«

«Здесь стоит отметить, что, хотя мы использовали наложение для переопределений на испанском языке в этом примере, поскольку оно не изменяет поведение API, мы могли бы так же легко определить этот модуль как расширение. И его может быть более уместно определить как расширение, учитывая, что его целью является переопределение свойств, найденных в англоязычном расширении над ним.

6. Заключение

В этом руководстве мы представили несколько методов, позволяющих сделать определение RAML API более модульным путем разделения общих конструкций во внешние файлы.

Во-первых, мы показали, как функция включения в RAML может использоваться для рефакторинга отдельных сложных значений свойств в многократно используемые внешние файловые модули, известные как типизированные фрагменты. Затем мы продемонстрировали способ использования функции включения для преобразования определенных наборов элементов в повторно используемые библиотеки. Наконец, мы расширили некоторые поведенческие и неповеденческие аспекты API за счет использования наложений и расширений.

Чтобы узнать больше о методах модуляризации RAML, посетите спецификацию RAML 1.0.

Next »

Define Custom RAML Properties Using Annotations

« Previous

Eliminate Redundancies in RAML with Resource Types and Traits