Skip to content
This repository has been archived by the owner on Sep 6, 2019. It is now read-only.

Latest commit

 

History

History
3590 lines (3241 loc) · 66 KB

RAML10-to-OAS30.md

File metadata and controls

3590 lines (3241 loc) · 66 KB

Export from Raml 1.0 to OAS 3.0

Table of Contents

  1. Ojective
  2. General Process
  3. The root of the document
  4. RAML Data types
    1. Type Declarations
    2. Built-in types
      1. Object Type
      2. Array Type
      3. Scalar Types
      4. Union Type
      5. Types defined using XML and JSON Schema
      6. User-defined Facets
      7. Type Expressions
      8. Inline Type Declarations
      9. XML Serialization of Type Instances
  5. Resources and Nested Resources
  6. Methods
    1. Headers
    2. Query Strings and Query Parameters
    3. Bodies
    4. Responses
  7. Security Schemes
  8. Examples
    1. Multiple Examples
    2. Single Example
  9. Annotations
  10. Lost semantics between translations
    1. Traits and Resource types
    2. Libraries
    3. Overlays and extensions
    4. Others

Objective

This document covers the following aspects of the conversion from RAML 1.0 to OAS 3.0:

  • how common concepts are being mapped
  • how language specific concepts are being resolved
  • lost semantics between languages

General Process

Before converting a RAML document to OAS 3.0, the converter resolves the following semantics:

  • traits
  • resource types
  • includes
  • libraries

The outcome is a "service model" that will be used to build a single OAS 3.0 document following the mapping described in this document.

During the conversion, the tool is not expected to preserve all semantical data. See section "The lost semantics between translations".

The root of the document

The root section of the RAML document describes the basic information about an API, such as its title and version. The root section also defines assets used elsewhere in the RAML document, such as types and traits.

RAML 1.0 Field Name OAS 3.0 Field Name
title info.title
description? info.description
version? info.version
baseUri? servers[].url
baseUriParameters? servers[].variables
protocols? schemes
mediaType? consumes, produces
documentation? No conversion to OAS.Lost semantic.
schemas? components.schemasSee Type Declarations mappings.
types? components.schemasSee Type Declarations mappings.
traits? No direct conversion to OAS.
This gap between specifications is being resolved as explained at Traits section.
See Traits and Resource Types.
resourceTypes? No direct conversion to OAS.
This gap between specifications is being resolved as explained at Resource Types section.
See Traits and Resource Types.
annotationTypes? No conversion to OAS.Lost semantic.
(annotationName)? x-annotation-annotationName vendor extension
See Annotations mappings.
securitySchemes? securitySchemes
securedBy? security
uses? No conversion to OAS.Lost semantic.
/[relativeUri] ? Mapped to `paths`

RAML data types

Types are split into four families: external, object, array, and scalar.

Types can define two kinds of members: properties and facets. Both are inherited.

  • Properties are regular, object oriented properties.

  • Facets are special configurations. You specialize types based on characteristics of facet values. Examples: minLength, maxLength

Only object types can declare properties. All types can declare facets.

To specialize a scalar type, you implement facets, giving already defined facets a concrete value.

To specialize an object type, you define properties.

Type Declarations

A type declaration references another type, or wraps or extends another type by adding functional facets (properties for example) or non-functional facets (a description for example), or is a type expression that uses other types.

Type declarations defined at root api file or external type declarations referenced through include or library / data type fragments are mapped to OAS 3.0 schemas with their schema objects.

RAML 1.0 Field Name OAS 3.0 Field Name
default? default
schema? inline declaration
type? type
example? example
examples? No conversion to OAS. Lost semantic.
displayName? No conversion to OAS. Lost semantic.
description? description
(annotationName)? x-annotation-annotationName vendor extension. See Annotations mappings.
facets? No conversion to OAS. See User-defined Facets mappings.
xml? xml. See XML Serialization mappings.
enum? enum
RAML 1.0 example OAS 3.0 Conversion

Example 1

#%RAML 1.0
title: type example
version: 1
types:
  ResourceLink:
    description: a description
    facets:
      a: string
      b: number
    properties:
      href: string
      rel:
        enum: [self, next, prev]
      method?:
        default: get
  ImageLink:
    properties:
      href: string
      rel:
        enum: [SmallImage, MediumImage, LargeImage]
openapi: 3.0.0
info:
  version: '1'
  title: type example
components:
  schemas:
    ResourceLink:
      properties:
        href:
          type: string
        rel:
          type: string
          enum:
            - self
            - next
            - prev
        method:
          type: string
          default: get
      type: object
      required:
        - href
        - rel
      description: a description
    ImageLink:
      properties:
        href:
          type: string
        rel:
          type: string
          enum:
            - SmallImage
            - MediumImage
            - LargeImage
      type: object
      required:
        - href
        - rel
paths: {}

Example 2

#%RAML 1.0
title: schema example
version: 1
schemas:
    song: |
        {
            "type": "object",
            "description": "main schema",
            "additionalProperties": true,
            "title": "a title",
            "properties": {
                "songTitle": {
                    "type": "string",
                    "required": true
                    },
                "albumId": {
                    "type": "string",
                    "required": true,
                    "minLength": 36,
                    "maxLength": 36
                }
            }
        }
openapi: 3.0.0
info:
  version: '1'
  title: schema example
components:
  schemas:
    song:
      type: object
      description: main schema
      additionalProperties: true
      title: a title
      required:
        - songTitle
        - albumId
      properties:
        songTitle:
          type: string
        albumId:
          type: string
          minLength: 36
          maxLength: 36
paths: {}

Example 3

#%RAML 1.0
title: type example
version: 1
types:
  song:
    schema: |
        {
            "type": "object",
            "description": "main schema",
            "additionalProperties": true,
            "title": "a title",
            "properties": {
                "songTitle": {
                    "type": "string",
                    "required": true
                    },
                "albumId": {
                    "type": "string",
                    "required": true,
                    "minLength": 36,
                    "maxLength": 36
                }
            }
        }
openapi: 3.0.0
info:
  version: '1'
  title: type example
components:
  schemas:
    song:
      type: object
      description: main schema
      additionalProperties: true
      title: a title
      required:
        - songTitle
        - albumId
      properties:
        songTitle:
          type: string
        albumId:
          type: string
          minLength: 36
          maxLength: 36
paths: {}

Built-in types

Object Type

RAML 1.0 Field Name OAS 3.0 Field Name
properties? properties
minProperties? minProperties
maxProperties? maxProperties
additionalProperties? additionalProperties.
discriminator? discriminator
discriminatorValue? No conversion to OAS. Lost semantic.
RAML 1.0 example OAS 3.0 Conversion

Example 4
additionalProperties not allowed

#%RAML 1.0
title: example
version: 1
types:
  Address:
   additionalProperties: false
   type: object
   properties:
     street: string
     city: string
     name: string
openapi: 3.0.0
info:
  version: '1'
  title: example
  description: ''
components:
  schemas:
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        name:
          type: string
      additionalProperties: false
      required:
        - street
        - city
        - name
paths: {}

Example 5
additionalProperties allowed. no restrictions

#%RAML 1.0
title: example
version: 1
types:
  Address:
   type: object
   properties:
     street: string
     city: string
     name: string
openapi: 3.0.0
info:
  version: '1'
  title: example
  description: ''
components:
  schemas:
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        name:
          type: string
      required:
        - street
        - city
        - name
paths: {}

Example 6
additionalProperties allowed. Only string

#%RAML 1.0
title: example
version: 1
types:
  Address:
   type: object
   properties:
     street: string
     city: string
     //: string
openapi: 3.0.0
info:
  version: "1.0"
  title: example
components:
  schemas:
    Address:
      properties:
        street:
          type: string
        city:
          type: string
      required:
        - street
        - city
      additionalProperties:
        type: string
paths: {}

Example 7
additionalProperties allowed.
Every property name has to follow a pattern. Value, string

#%RAML 1.0
title: example
version: 1
types:
  Address:
   type: object
   properties:
     street: string
     city: string
     /^note\d+$/: string
openapi: 3.0.0
info:
  version: "1.0"
  title: example
components:
  schemas:
    Address:
      properties:
        street:
          type: string
        city:
          type: string
      required:
        - street
        - city
      additionalProperties:
        type: string
paths: {}

Example 8
discriminator facet.

#%RAML 1.0
title: example
version: 1
types:
  Person:
   type: object
   discriminator: kind
      # refers to the `kind` property of object `Person`
   properties:
     kind: string
      # contains name of the kind of a `Person` instance
     name: string
  Employee:
     # kind may equal to `Employee; default value for `discriminatorValue`
   type: Person
   properties:
     employeeId: string
  User:
     # kind may equal to `User`; default value for `discriminatorValue`
   type: Person
   properties:
     userId: string
openapi: 3.0.0
info:
  version: '1'
  title: example
components:
  schemas:
    Person:
      type: object
      discriminator:
        propertyName: kind
      properties:
        kind:
          type: string
        name:
          type: string
      required:
        - kind
        - name
    Employee:
      allOf:
        - $ref: '#/components/schemas/Person'
        - type: object
          properties:
            employeeId:
              type: string
          required:
            - employeeId
    User:
      allOf:
        - $ref: '#/components/schemas/Person'
        - type: object
          properties:
            userId:
              type: string
          required:
            - userId
paths: {}

Array Type

RAML 1.0 Field Name OAS 3.0 Field Name
uniqueItems? uniqueItems
items? items
minItems? minItems
maxItems? maxItems
RAML 1.0 example OAS 3.0 Conversion

Example 9

#%RAML 1.0
title: example
version: 1
types:
  Email: # normal object type declaration
    type: object
    properties:
      subject: string
      body: string
  EmailsLong: # array type declaration
    type: array
    items: Email
    minItems: 1
    uniqueItems: true
  EmailsShort:
     # array type declaration using type expression
     shortcut
    type: Email[] # '[]' expresses an array
    minItems: 1
    uniqueItems: true
    example: # example that contains array
      - # start item 1
        subject: My Email 1
        body: This is the text for email 1.
      - # start item 2
        subject: My Email 2
        body: This is the text for email 2.
openapi: 3.0.0
info:
  version: '1'
  title: example
components:
  schemas:
    Email:
      properties:
        subject:
          type: string
        body:
          type: string
      type: object
      required:
        - subject
        - body
    EmailsLong:
      type: array
      uniqueItems: true
      items:
        $ref: '#/components/schemas/Email'
      minItems: 1
    EmailsShort:
      type: array
      example:
        - subject: My Email 1
          body: This is the text for email 1.
        - subject: My Email 2
          body: This is the text for email 2.
      uniqueItems: true
      minItems: 1
      items:
        $ref: '#/components/schemas/Email'
paths: {}

Scalar Types

String

String types are converted as strings. The following facets are available:

RAML 1.0 Field Name OAS 3.0 Field Name
pattern? pattern
minLength? minLength
minLength? maxLength
RAML 1.0 example OAS 3.0 Conversion

Example 10

#%RAML 1.0
title: example
version: 1
types:
  Email:
    type: string
    minLength: 2
    maxLength: 6
    pattern: ^note\d+$
openapi: 3.0.0
info:
  version: '1'
  title: example

components:
  schemas:
    Email:
      type: string
      minLength: 2
      maxLength: 6
      pattern: ^note\d+$
paths: {}

Number / Integer

Number types are converted to integer, long, float depending on type and format. The following facets are available:

RAML 1.0 Field Name AS 3.0 Field Name
minimum? minimum
maximum? maximum
format? format
multipleOf? multipleOf
RAML 1.0 example OAS 3.0 Conversion

Example 11

#%RAML 1.0
title: example
version: 1
types:
  Weight:
    type: number
    minimum: 3
    maximum: 5
    format: float
    multipleOf: 4
  Age:
    type: integer
    minimum: 3
    maximum: 5
    format: int8
    multipleOf: 1
openapi: 3.0.0
info:
  version: '1'
  title: example
components:
  schemas:
    Weight:
      type: number
      minimum: 3
      maximum: 5
      format: float
      multipleOf: 4
    Age:
      type: integer
      minimum: 3
      maximum: 5
      format: int8
      multipleOf: 1
paths: {}

Boolean

A JSON boolean without any additional facets.

RAML 1.0 example Converts to OAS 3.0 like this

Example 12

#%RAML 1.0
title: example
version: 1
types:
  isMarried:
    type: boolean
openapi: 3.0.0
info:
  version: '1'
  title: example
components:
  schemas:
    isMarried:
      type: boolean
paths: {}

Date

RAML 1.0 Field Name OAS 3.0 Field Name
The "full-date" notation of RFC3339, namely yyyy-mm-dd.
type: date-only
type: string
format: date
The "partial-time" notation of RFC3339, namely hh:mm:ss[.ff...].
type: time-only
type: string
Lost semantic.
Combined date-only and time-only with a separator of "T", namely yyyy-mm-ddThh:mm:ss[.ff...]. type: datetime-only type: string
Lost semantic.
A timestamp in one of the following formats:
  • if the format is omitted or set to rfc3339, uses the "date-time" notation of RFC3339;
  • if format is set to rfc2616, uses the format defined in RFC2616.
type: datetime
if format = RFC3339
  type: string
  format: date-time
if not,
  type: string

Lost semantic.

RAML 1.0 example OAS 3.0 Conversion

Example 13

#%RAML 1.0
title: example
version: 1
types:
  birthday:
    type: date-only
      # no implications about time or offset
    example: 2015-05-23
  lunchtime:
    type: time-only
      # no implications about date or offset
    example: 12:30:00
  fireworks:
    type: datetime-only
      # no implications about offset
    example: 2015-07-04T21:00:00
  created:
    type: datetime
    example: 2016-02-28T16:41:41.090Z
    format: rfc3339
      # the default, so no need to specify
  If-Modified-Since:
    type: datetime
    example: Sun, 28 Feb 2016 16:41:41 GMT
    format: rfc2616
      # this time it's required, otherwise, the example format is invalid
openapi: 3.0.0
info:
  version: ''
  title: example
components:
  schemas:
    birthday:
      type: string
      format: date
      example: 2015-05-23
    lunchtime:
      type: string
      example: 12:30:00
    fireworks:
      type: string
      example: 2015-07-04T21:00:00
    created:
      type: string
      example: 2016-02-28T16:41:41.090Z
      format: rfc3339
    If-Modified-Since:
      type: string
      example: Sun, 28 Feb 2016 16:41:41 GMT
paths: {}

File

The ​file​ type can constrain the content to send through forms. When this type is used in the context of web forms it SHOULD be represented as a valid file upload in JSON format. File content SHOULD be a base64-encoded string.

Models of file type are converted to OAS as strings. File specific facets are lost, although it is possible to keep minLength and maxLength since they are string facets as well.

RAML 1.0 Field Name OAS 3.0 Field Name
fileTypes? No conversion to OAS. Lost semantic.
minLength? minLength
maxLength? maxLength
RAML 1.0 example OAS 3.0 Conversion

Example 14

#%RAML 1.0
title: example
types:
  userPicture:
    type: file
    fileTypes: ['image/jpeg', 'image/png']
    maxLength: 307200
  customFile:
    type: file
    fileTypes: ['*/*'] # any file type allowed
    maxLength: 1048576
openapi: 3.0.0
info:
  version: ''
  title: example
components:
  schemas:
    userPicture:
      type: string
      format: binary
      maxLength: 307200
    customFile:
      type: string
      format: binary
      maxLength: 1048576
paths: {}

Union Type

A union type is used to describe data by any of several types. A union type is declared via a type expression that combines 2 or more types delimited by pipe (|) symbols; these combined types are referred to as the union type's super types.

OAS allows combining and extending model schemas using the allOf property of JSON Schema, in effect offering model composition. Nevertheless, there are more complex union scenarios where allOf is not enough. When this is the case, union type is converted to an unrestricted object type. Lost semantics.

RAML 1.0 OAS 3.0 Conversion

Example 15
Two types and a third type which is a union of those two types

#%RAML 1.0
title: My API With Types
types:
  Phone:
    type: object
    properties:
      manufacturer:
        type: string
      numberOfSIMCards:
        type: number
      kind: string
  Notebook:
    type: object
    properties:
      manufacturer:
        type: string
      numberOfUSBPorts:
        type: number
      kind: string
  Device:
    type: Phone | Notebook
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
components:
  schemas:
    Phone:
      properties:
        manufacturer:
          type: string
        numberOfSIMCards:
          type: number
        kind:
          type: string
      type: object
      required:
        - manufacturer
        - numberOfSIMCards
        - kind
    Notebook:
      properties:
        manufacturer:
          type: string
        numberOfUSBPorts:
          type: number
        kind:
          type: string
      type: object
      required:
        - manufacturer
        - numberOfUSBPorts
        - kind
    Device:
      anyOf:
        - "$ref": "#/components/schemas/Phone"
        - "$ref": "#/components/schemas/Notebook"
paths: {}

Example 16
More complex example of a union type used in a multiple inheritance type expression

#%RAML 1.0
title: My API With Types
types:
   HasHome:
     type: object
     properties:
       homeAddress: string
   Cat:
     type: object
     properties:
       name: string
       color: string
   Dog:
     type: object
     properties:
       name: string
       fangs: string
   HomeAnimal: [ HasHome ,  Dog | Cat ]
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
components:
  schemas:
    HasHome:
      properties:
        homeAddress:
          type: string
      type: object
      required:
        - homeAddress
    Cat:
      properties:
        name:
          type: string
        color:
          type: string
      type: object
      required:
        - name
        - color
    Dog:
      properties:
        name:
          type: string
        fangs:
          type: string
      type: object
      required:
        - name
        - fangs
    HomeAnimal:
      allOf:
        - "$ref": "#/components/schemas/HasHome"
        - anyOf:
          - "$ref": "#/components/schemas/Dog"
          - "$ref": "#/components/schemas/Cat"
paths: {}

Example 17

#%RAML 1.0
title: My API With Types
types:
  types:
     HasHome:
       type: object
       properties:
         homeAddress: string
     IsOnFarm:
       type: object
       properties:
         farmName: string
     Cat:
       type: object
       properties:
         name: string
         color: string
     Dog:
       type: object
       properties:
         name: string
         fangs: string
     Parrot:
       type: object
       properties:
         name: string
         color: string
     HomeAnimal: [ HasHome | IsOnFarm ,
                   Dog | Cat | Parrot ]
openapi: 3.0.0
info:
  version: ''
  title: "My API With Types"
components:
  schemas:
    HasHome:
      type: object
      properties:
      homeAddress:
        type: string
      required:
      - homeAddress
    IsOnFarm:
      type: object
      properties:
      farmName:
        type: string
      required:
      - farmName
    Cat:
      type: object
      properties:
      name:
        type: string
      color:
        type: string
      required:
      - name
      - color
    Dog:
      type: object
      properties:
      name:
        type: string
      fangs:
        type: string
      required:
      - name
      - fangs
    Parrot:
      type: object
      properties:
      name:
        type: string
      color:
        type: string
      required:
      - name
      - color
    HomeAnimal:
      allOf:
        - anyOf:
          - "$ref": "#/components/schemas/HasHome"
          - "$ref": "#/components/schemas/IsOnFarm"
        - anyOf:
          - "$ref": "#/components/schemas/Cat"
          - "$ref": "#/components/schemas/Dog"
          - "$ref": "#/components/schemas/Parrot"
paths: {}

Example 18

#%RAML 1.0
title: My API With Types
types:
  ErrorModel:
    type: object
    properties:
      message:
        type: string
      code:
        type: integer
        minimum: 100
        maximum: 600
  ExtendedErrorModel:
    type: ErrorModel
    properties:
       rootCause:
         type: string
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
components:
  schemas:
    ErrorModel:
      type: object
      required:
      - message
      - code
      properties:
        message:
          type: string
        code:
          type: integer
          minimum: 100
          maximum: 600
    ExtendedErrorModel:
      allOf:
      - $ref: '#/components/schemas/ErrorModel'
      - type: object
        properties:
          rootCause:
            type: string
        required:
        - rootCause
paths: {}

Types defined using XML and JSON Schema

RAML 1.0 OAS 3.0 Conversion

Example 19 Assuming Person.json

{
 "type": "object",
 "description": "Person details",
 "properties": {
   "firstName": { "type": "string" },
   "lastName": { "type": "string" },
   "nationality": { "type": "string" }
 },
 "required": [ "firstName", "lastName" ]
}

Assuming api definition this way

#%RAML 1.0
title: My API With Types
types:
  Person: !include Person.json
openapi: 3.0.0
info:
  version: ''
  title: "My API With Types"
components:
  schemas:
    Person:
      description: "Person details"
      type: object
      properties:
        firstName:
          type: string
        lastName:
          type: string
        nationality:
          type: string
      required:
        - firstName
        - lastName
        - nationality
paths: {}

Example 20 Assuming Person.json

{
 "type": "object",
 "description": "Person details",
 "properties": {
   "firstName": { "type": "string" },
   "lastName": { "type": "string" },
   "nationality": { "type": "string" }
 },
 "required": [ "firstName", "lastName" ]
}

Assuming api definition this way

#%RAML 1.0
title: My API With Types
/person:
  get:
    responses:
      200:
        body:
          application/json:
            type: !include Person.json
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
paths:
  /persons:
    get:
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {
                  "description": "Foo details",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "ownerName": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ],
                  "type" : "object"
                }

Example 21 References to Inner Elements

#%RAML 1.0
title: My API With Types
types:
  Foo:
    type: !include elements.xsd#Foo
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
components:
  schemas:
    Foo:
      $ref: "elements.xsd#Foo"
paths: {}

User-defined Facets

In RAML 1.0, in addition to the built-in facets, you can declare user-defined facets for any data type.

#%RAML 1.0
title: API with Types
types:
  CustomDate:
    type: date-only
    facets:
      onlyFutureDates?: boolean # optional  in `PossibleMeetingDate`
      noHolidays: boolean # required in `PossibleMeetingDate`
  PossibleMeetingDate:
    type: CustomDate
    noHolidays: true

OAS does not have a similar capability, so conversion is not possible here. See Lost semantics.

RAML 1.0 OAS 3.0 Conversion

Example 22

#%RAML 1.0
title: user-defined facets
version: 1
types:
  stringWithMimeType:
    type: string
    facets: #this does not maps directly to oas 3.0
      mime: string
  json:
    type: stringWithMimeType
    mime: "application/json" #this does not maps directly to oas 3.0
openapi: 3.0.0
info:
  version: ''
  title: user-defined facets
paths: {}
components:
  schemas:
    stringWithMimeType:
      type: string
    json:
      $ref: '#/components/schemas/stringWithMimeType'

Type Expressions

Type expressions provide a powerful way of referring to, and even defining, types. Type expressions can be used wherever a type is expected. The simplest type expression is just the name of a type. Using type expressions, you can devise type unions, arrays, maps, and other things.

Expression RAML example OAS Conversion
Person
The simplest type expression: A single type

Example 23

#%RAML 1.0
title: API with Types
types:
  User:
    type: object
    properties:
      firstName: string
      lastName:  string
      age:       number
/users/{id}:
  get:
    responses:
      200:
        body:
          application/json:
            type: User
openapi: 3.0.0
info:
  version: ''
  title: API with Types
  description: ''
paths:
  '/users/{id}':
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: GET_users-id
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        firstName:
          type: string
        lastName:
          type: string
        age:
          type: number
      required:
            - firstName
            - lastName
            - age
Person[]
An array of Person objects

Example 24

#%RAML 1.0
title: API with types
types:
  Email:
    type: object
    properties:
      subject: string
      body: string
  EmailsLong:
    type: array
    items: Email
    minItems: 1
    uniqueItems: true
  EmailsShort:
    type: Email[]
    minItems: 1
    uniqueItems: true
/mail:
  get:
    responses:
      200:
        body:
          application/json:
            type: EmailsShort
openapi: 3.0.0
info:
  version: ''
  title: API with types
paths:
  /mail:
    get:
      operationId: GET_mail
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailsShort'
components:
  schemas:
    Email:
      type: object
      properties:
        subject:
          type: string
        body:
          type: string
      required:
        - subject
        - body
    EmailsLong:
      type: array
      uniqueItems: true
      items:
        $ref: '#/components/schemas/Email'
      minItems: 1
    EmailsShort:
      type: array
      uniqueItems: true
      minItems: 1
      items:
        $ref: '#/components/schemas/Email'
string[]
An array of string scalars

Example 25

#%RAML 1.0
title: API with types
types:
  StringArray:
  # normal array of strings type declaration
    type: array
    items: string
  IntegerArray:
  # array of integer type declaration
    type: integer[]
    minItems: 1
    uniqueItems: true
  DateArray:
  # array type declaration using
  # type expression shortcut
    type: date-only[]
    example:
      - 2015-05-23
      - 2015-05-19
/mail:
  get:
    responses:
      200:
        body:
          application/json:
            type: DateArray
openapi: 3.0.0
info:
  version: '1.0'
  title: API with types
  description: ''
paths:
  /mail:
    get:
      operationId: GET_mail
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DateArray'
components:
  schemas:
    StringArray:
      type: array
      items:
        type: string
    IntegerArray:
      type: array
      uniqueItems: true
      minItems: 1
      items:
        type: integer
    DateArray:
      type: array
      example:
        - '2015-05-23'
        - '2015-05-19'
      items:
        type: string
        format: date
string[][]
A bi-dimensional array of string scalars

Example 25.1

#%RAML 1.0
title: API with types
types:
  StringArray:
  # normal array of strings
  # type declaration
    type: array
    items: string
  IntegerArray:
  # array of integer type declaration
    type: integer[][]
  DateArray:
  # array type declaration using
  # type expression shortcut
    type: date-only[]
    example:
      - 2015-05-23
      - 2015-05-19
/mail:
  get:
    responses:
      200:
        body:
          application/json:
            type: IntegerArray
openapi: 3.0.0
info:
  version: ''
  title: API with types
  description: ''
paths:
  /mail:
    get:
      operationId: GET_mail
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegerArray'
components:
  schemas:
    StringArray:
      type: array
      items:
        type: string
    IntegerArray:
      type: array
      items:
        type: array
        items:
          type: integer
    DateArray:
      type: array
      example:
        - '2015-05-23'
        - '2015-05-19'
      items:
        type: string
        format: date
string | Person
A union type made of members of string OR Person
#%RAML 1.0
title: API with types
types:
  UnionType:
    type: string | Person
  Person:
      type: object
/union:
  get:
    responses:
      200:
        body:
          application/json:
            type: UnionType
openapi: 3.0.0
info:
  version: ''
  title: API with types
  description: ''
paths:
  /union:
    get:
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnionType'
components:
  schemas:
    UnionType:
      anyOf:
        - type: string
        - $ref: '#/components/schemas/Person'
    Person:
      type: object
(string | Person)[]
An array of the type shown above
#%RAML 1.0
title: API with types
types:
  UnionArray:
    type: (string | Person)[]
  Person:
      type: object
/union:
  get:
    responses:
      200:
        body:
          application/json:
            type: UnionArray
openapi: 3.0.0
info:
  version: ''
  title: API with types
  description: ''
paths:
  /union:
    get:
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnionArray'
components:
  schemas:
    UnionArray:
      type: array
      items:
        anyOf:
          - type: string
          - $ref: '#/components/schemas/Person'
    Person:
      type: object

Inline Type Declarations

You can declare inline/anonymous types everywhere a type can be referenced except in a Type Expression.

RAML 1.0 OAS 3.0 Conversion

Example 26

#%RAML 1.0
title: My API With Types
/users/{id}:
  get:
    responses:
      200:
        body:
          application/json:
            type: object
            properties:
              firstname:
                type: string
              lastname:
                type: string
              age:
                type: number
openapi: 3.0.0
info:
  version: ''
  title: My API With Types
paths:
  '/users/{id}':
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: GET_users-id
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                properties:
                  firstname:
                    type: string
                  lastname:
                    type: string
                  age:
                    type: number

XML Serialization of Type Instances

A RAML 1.0 xml node maps to OAS 3.0 xml node this way:

RAML 1.0 Field Name OAS 3.0 Field Name
attribute? attribute
wrapped? wrapped
name? name
namespace? namespace
prefix? prefix
RAML 1.0 OAS 3.0 Conversion

Example 27

#%RAML 1.0
title: API Platform V2 API
types:
  Person:
    properties:
      name:
        type: string
        xml:
          attribute: true
              # serialize it as an XML attribute
          name: "fullname"
             # attribute should be called fullname
      addresses:
        type: Address[]
        xml:
          wrapped: true
            # serialize it into its own
            # <addresses>...</addresses> XML element
  Address:
    properties:
      street: string
      city: string
openapi: 3.0.0
info:
  version: ''
  title: API Platform V2 API
components:
  schemas:
    Person:
      properties:
        name:
          type: string
          xml:
            attribute: true
            name: fullname
        addresses:
          type: array
          xml:
            wrapped: true
          items:
            $ref: '#/components/schemas/Address'
      type: object
      required:
        - name
        - addresses
    Address:
      properties:
        street:
          type: string
        city:
          type: string
      type: object
      required:
        - street
        - city
paths: {}

Resources and Nested Resources

A resource is identified by its relative URI. It is converted to OAS as a path.

RAML 1.0 Field Name OAS 3.0 Field Name
displayName? No conversion to OAS.
Lost semantics.
description? No conversion to OAS.
Lost semantics.
(annotationName)? x-annotation-annotationName vendor extension
See Annotations mappings.
get?
patch?
put?
post?
delete?
options?
head?
get
patch
put
post
delete
options
head
is? No conversion to OAS.
Lost semantics.
type? $ref, reference to schemas created as consequence of resource type conversion.
Lost semantics.
securedBy? Security definitions that apply to all methods in the path; consequently, definitions will be converted to a OAS security declaration for each method. This might be redefined at the method level.
See Security Schemes mappings.
uriParameters? parameters. path type

Methods

RESTful API methods are operations that are performed on a resource. Methods have properties that match OAS Operation Object attributes that are converted as follows:

RAML 1.0 Field Name OAS 3.0 Field Name
displayName? operationId
description? description
(annotationName)? x-annotation-annotationName vendor extension
See Annotations mappings.
queryParameters? parameters. in: query.
Examples at Query parameters section.
headers? parameters. in: header
Examples at Headers section.
queryString? parameters. in: query.
responses? responses.
Examples at Responses section..
body? requestBody
Examples at Bodies section.
protocols? No conversion to OAS.
Lost semantics.
is? No conversion to OAS.
Lost semantics.
securedBy? security. The security schemes that apply to this method.

Headers

RAML 1.0 OAS 3.0 Conversion

Example 28

#%RAML 1.0
title: headers example
version: 1
/jobs:
 post:
   description: Create a job
   headers:
     Zencoder-Api-Key:
       description: The API key needed to
                    create a new job
openapi: 3.0.0
info:
  version: '1'
  title: headers example
paths:
  /jobs:
    post:
      operationId: POST_jobs
      description: Create a job
      parameters:
        - name: Zencoder-Api-Key
          in: header
          description: The API key needed to create a new job
          required: true
          schema:
            type: string
      responses:
        default:
          description: ''

Example 29

#%RAML 1.0
title: headers example
version: 1
/jobs2:
 get:
   headers:
     X-Dept:
       type: array
       description: |
         A department code to be charged.
         Multiple of such headers are allowed.
       items:
         pattern: ^\d+\-\w+$
         example: 230-OCTO
openapi: 3.0.0
info:
 version: "1"
 title: "headers example"
paths:
 "/jobs2":
  get:
   operationId: GET_jobs2
   parameters:
    - name: "X-Dept"
      in: header
      description: A department code to be charged.
            Multiple of such headers are allowed
      required: true
      schema:
        type: array
        items:
          type: string
   responses:
    default:
     description: ""

Query Strings and Query Parameters

RAML 1.0 OAS 3.0 Conversion

Example 30

#%RAML 1.0
title: GitHub API
/users:
  get:
    description: Get a list of users
    queryParameters:
      page:
        description: Specify the page that you want to retrieve
        type:        integer
        required:    true
        example:     1
      per_page:
        description: Specify the amount of items that will be retrieved per page
        type:        integer
        minimum:     10
        maximum:     200
        default:     30
        example:     50
openapi: 3.0.0
info:
  version: ''
  title: GitHub API
paths:
  /users:
    get:
      operationId: GET_users
      description: Get a list of users
      parameters:
        - name: page
          in: query
          description: Specify the page that you
                       want to retrieve
          required: true
          schema:
            type: integer
        - name: per_page
          in: query
          description: Specify the amount of items that
                       will be retrieved per page
          required: true
          schema:
            type: integer
            default: 30
            minimum: 10
            maximum: 200
      responses:
        default:
          description: ''

Bodies

RAML 1.0 OAS 3.0 Conversion

Example 31

#%RAML 1.0
title: Example of request bodies
mediaType: application/json
types:
  User:
    properties:
      firstName:
      lastName:
/users:
  post:
    body:
      type: User
/groups:
  post:
    body:
      application/json:
        properties:
          groupName:
          deptCode:
            type: number
      text/xml:
        type: !include schemas/group.xsd
openapi: 3.0.0
info:
 version: ''
 title: Example of request bodies
paths:
  /users:
    post:
      operationId: POST_users
      requestBody:
        description: ''
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      responses:
        default:
          description: ''
  /groups:
    post:
      operationId: POST_groups
      requestBody:
        description: ''
        required: true
        content:
          text/xml:
            schema:
              $ref: "schemas/group.xsd#" # this may be wrong
          application/json:
            schema:
              type: object
      responses:
        default:
          description: ''
components:
  schemas:
    User:
      properties:
        firstName:
          type: string
        lastName:
          type: string
      type: object
      required:
        - firstName
        - lastName

Responses

RAML 1.0 Field Name OAS 3.0 Field Name
description? description
(annotationName) x-annotation-annotationName vendor extension
See Annotations mappings.
headers? headers
body? body

Security Schemes

Security Schemes are converted to OAS as Security Schemes. RAML supports the following built-in security scheme types that are converted as follows:

RAML 1.0 Type OAS 3.0 Type
OAuth 1.0 oauth
OAuth 2.0 oauth2
Basic Authentication basic
Digest Authentication digest
Pass Through apiKey
x-{other} Custom security definition. x-schemeName
RAML 1.0 Field Name OAS 3.0 Field Name
type type
displayName? No conversion to OAS
Lost semantics.
description? description
describedBy? Depending on type
OAuth2.0 headers
queryParameters
responses
No conversion to OAS
Lost semantics.
Pass Through headers
queryParameters
in: header
x-other headers
queryParameters
in:header
settings? Depending on type
OAuth1.0 requestTokenUri
authorizationUri
tokenCredentialsUri
signatures
No conversion to OAS.
Lost semantics.
OAuth2.0 authorizationUri
accessTokenUri
authorizationGrants
scopes
authorizationUrl
tokenUrl
flow
scopes
Basic Authentication Not Applicable Not Applicable
Digest Authentication Not Applicable Not Applicable
Pass Through Not Applicable Not Applicable

Examples

RAML supports either the definition of multiple examples or a single one for any given instance of a type declaration.

Multiple Examples

Multiples named examples are supported

Single Example

Value faces and annotations will be used to map to an OAS example node when possible. See Lost semantics.

RAML 1.0 OAS 3.0 conversion

Example 36

#%RAML 1.0
title: API with Examples
types:
  User:
    type: object
    properties:
      name: string
      lastname: string
    example:
      name: Bob
      lastname: Marley
openapi: 3.0.0
info:
  version: ''
  title: API with Examples
components:
  schemas:
    User:
      type: object
      example:
        name: Bob
        lastname: Marley
      properties:
        name:
          type: string
        lastname:
          type: string
      required:
        - name
        - lastname
paths: {}

Example 37

#%RAML 1.0
title: API with Examples
types:
  User:
    type: object
    properties:
      name: string
      lastname: string
    examples:
      one:
        name: Bob
        lastname: Marley
      two:
        name: Paul
        lastname: Newman
openapi: 3.0.0
info:
  version: ''
  title: API with Examples
paths: {}
components:
  schemas:
    User:
      type: object
      properties:
        name:
          type: string
        lastname:
          type: string
      required:
        - name
        - lastname
      example:
        one:
          name: Bob
          lastname: Marley
        two:
          name: Paul
          lastname: Newman

Example 38

#%RAML 1.0
title: API with Examples
types:
  User:
    type: object
    properties:
      name: string
      lastname: string
    example:
      name: Bob
      lastname: Marley
  Org:
    type: object
    properties:
      name: string
      address?: string
      value? : string
/organisation:
  post:
    headers:
      UserID:
        description: the identifier for the user
          that posts a new organisation
        type: string
        example: SWED-123 # single scalar example
    body:
      application/json:
        type: Org
        example: # single request body example
          value: # needs to be declared since type contains 'value' property
            name: Doe Enterprise
            value: Silver
  get:
    description: Returns an organisation entity.
    responses:
      201:
        body:
          application/json:
            type: Org
            examples:
              acme:
                name: Acme
              softwareCorp:
                value: # validate against the available facets for the map value of an example
                  name: Software Corp
                  address: 35 Central Street
                  value: Gold # validate against instance of the `value` property
openapi: 3.0.0
info:
  version: ""
  title: "API with Examples"
paths:
  "/organisation":
    get:
      operationId: GET_organisation
      description: "Returns an organisation entity."
      responses:
        201:
          description: ""
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Org"
    post:
      operationId: POST_organisation
      requestBody:
        description: ''
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Org"
      parameters:
        - name: UserID
          in: header
          description: "the identifier for the user that posts a new organisation"
          required: true
          schema:
            type: string
      responses:
        default:
          description: ""
components:
  schemas:
    User:
      type: object
      example:
        name: Bob
        lastname: Marley
      properties:
        name:
          type: string
        lastname:
          type: string
      required:
        - name
        - lastname
    Org:
      type: object
      properties:
        name:
          type: string
        address:
          type: string
        value:
          type: string
      required:
        - name

Example 39

#%RAML 1.0
title: Using strict=false API
/person:
  get:
    queryParameters:
      sort?:
        type: string[]
        example:
          strict: false
          value: ?sort=givenName&sort=surname,asc
openapi: 3.0.0
info:
  version: ''
  title: Using strict=false API
paths:
  /person:
    get:
      operationId: GET_person
      parameters:
        - name: sort
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        default:
          description: ''

Annotations

Annotations will be mapped into vendor extensions, with the following naming standard:

(annotationName) will be converted as x-annotation-annotationName

If an annotation with the form of (oas-name) is present at the RAML document, they will be ignored by Export process. This kind of annotations were created by a previous OAS → RAML conversion and current version of Converter is not using those values to bring back original nodes. (Lost semantics.)

Lost semantics between translations

Although both specifications (OAS 3.0 and RAML 1.0) have various aspects in common, RAML includes features that do not have an equivalent in OAS. So, when converting from a RAML document to OAS document some decisions are taken in order to deal with non-supported features. The following section describes RAML 1.0 concepts that will be lost or how concept differences are mapped to convert a RAML 1.0 document into OAS 3.0.

Traits and Resource Types

There are many advantages of reusing patterns across multiple resources and methods.

Traits and resource types are the tools that RAML provides to enable reuse and standardization.

A trait, like a method, can provide method-level nodes such as description, headers, query string parameters, and responses. OAS has a similar, but not exact concept: global parameters and global responses. When reuse is possible, traits are resolved as follows:

  • Traits of header and the queryParameters type are mapped to OAS global parameters.
  • Traits of response type are mapped to OAS global responses.
  • QueryParameter traits of multiple attributes are split into several global parameters.

There are corner cases where it is not possible to map to reusable components. When this is the scenario, trait definitions are used to create a parameters or responses at the method level.

RAML 1.0 example OAS 3.0 Conversion

Example 32

#%RAML 1.0
title: traits example
traits:
  imageable:
      queryParameters:
        imageType:
          description: Comma ,
             separated list just like in
             example. One alone may be present
          type: string
          required: false
          default: SmallImage
          example:
           TinyImage,SwatchImage,
           SmallImage,MediumImage,
           LargeImage
/items:
   get:
      is: [imageable]
openapi: 3.0.0
info:
  version: ''
  title: traits example
components:
  parameters:
    trait-imageable-imageType:
      name: imageType
      in: query
      description: 'Comma , separated list just like in example. One alone may be present'
      required: false
      schema:
        type: string
        default: SmallImage
paths:
  /items:
    get:
      operationId: GET_items
      parameters:
        - $ref: '#/components/parameters/trait-imageable-imageType'
      responses:
        default:
          description: ''

Example 33

#%RAML 1.0
title: traits example
traits:
  searchable:
    queryParameters:
      name:
        type: string
        required: false
        example: Deep Steep Honey Bubble Bath
      type:
        type: string
        required: false
        example: Oils
      brand:
        type: string
        required: false
        example: Naturtint
/items:
   get:
      is: [searchable]
openapi: 3.0.0
info:
  version: ''
  title: traits example
components:
  parameters:
    trait-searchable-name:
      name: name
      in: query
      required: false
      schema:
        type: string
    trait-searchable-type:
      name: type
      in: query
      required: false
      schema:
        type: string
    trait-searchable-brand:
      name: brand
      in: query
      required: false
      schema:
        type: string
paths:
  /items:
    get:
      operationId: GET_items
      parameters:
        - $ref: '#/components/parameters/trait-searchable-name'
        - $ref: '#/components/parameters/trait-searchable-type'
        - $ref: '#/components/parameters/trait-searchable-brand'
      responses:
        default:
          description: ''

Example 34

#%RAML 1.0
title: traits example
traits:
  imageable:
      queryParameters:
        imageType:
          description: Comma ,
             separated list just like in
             example. One alone may be present
          type: string
          required: false
          default: SmallImage
          example:
           TinyImage,SwatchImage,
           SmallImage,MediumImage,
           LargeImage
   accessToken:
     headers:
       token:
         description: access token
         type: string
         example: password
/items:
   get:
      is: [imageable,accessToken]
openapi: 3.0.0
info:
  version: ''
  title: traits example
components:
  parameters:
    trait-imageable-imageType:
      name: imageType
      in: query
      description: 'Comma , separated list just
            like in example. One alone may be present'
      required: false
      schema:
        type: string
        default: SmallImage
    trait-accessToken-token:
      name: token
      in: header
      description: access token
      required: false
      schema:
        type: string
paths:
  /items:
    get:
      operationId: GET_items
      parameters:
        - $ref: '#/components/parameters/trait-imageable-imageType'
        - $ref: '#/components/parameters/trait-accessToken-token'
      responses:
        default:
          description: ''

Example 35

#%RAML 1.0
title: traits example
traits:
  imageable:
      queryParameters:
        imageType:
          description: Comma ,
             separated list just like in
             example. One alone may be present
          type: string
          required: false
          default: SmallImage
          example:
            TinyImage,SwatchImage,
            SmallImage,MediumImage,
            LargeImage
   accessToken:
     headers:
       token:
         description: access token
         type: string
         example: password
   hasFound:
     responses:
      200:
        body:
          application/json:
          type: Item
/items:
   get:
      is: [imageable,accessToken]
openapi: 3.0.0
info:
  version: ''
  title: traits example
components:
  parameters:
    trait-imageable-imageType:
      name: imageType
      in: query
      description: 'Comma , separated list just
            like in example. One alone may be present'
      required: false
      schema:
        type: string
        default: SmallImage
    trait-accessToken-token:
      name: token
      in: header
      description: access token
      required: false
      schema:
        type: string
  responses:
    trait-hasFound-200:
      description: ''
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Item' #missing in this example
paths:
  /prueba:
    get:
      operationId: GET_prueba
      parameters:
        - $ref: '#/components/parameters/trait-imageable-imageType'
        - $ref: '#/components/parameters/trait-accessToken-token'
      responses:
        '200':
          $ref: '#/components/responses/trait-hasFound-200'

Besides traits, defining resource types helps reusing patterns across multiple resources. A resource type, like a resource, can specify security schemes, methods, and other nodes. A resource that uses a resource type inherits its nodes. A resource type can also use, and thus inherit from, another resource type. Resource types and resources are related through an inheritance chain pattern.

When exporting to OAS, resource type schemas cannot be mapped directly since this semantic is lost. Nevertheless, they are resolved through expansion in the form of paths, parameters or responses.

Libraries

Will be not really mapped. The conversion should work on the expanded tree. Any library information is lost since one single file with library and root raml information will be generated.

Overlays and extensions

Overlays and extensions are not actually be mapped to anything. When converting - overlays and extensions should have been applied by the parser already.

Others

  • documentation
  • annotationTypes
  • uses
  • displayName (?)
  • annotations (if created during OAS-->RAML conversion. Converter does not yet reuse those annotations to bring back the original nodes.)
  • pattern when used to validate additionalProperties names
  • format in some scenarios (when converting date types)
  • file type facets: fileTypes
  • file type facets: minLength ( TODO: really?)
  • file type facets: maxLength ( TODO: really?)
  • discriminatorValue
  • custom facets
  • resource description
  • protocols
  • traits usage at method or resource level
  • example for nodes where example is not supported. Example specific facets are not supported either.
  • references to inner elements of xml schemas
  • RAML original body when there are different definitions for different mediatypes