Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

An Overview of RAML 1.0

DZone's Guide to

An Overview of RAML 1.0

With RAML 1.0, APIs are much more readable, and data types can be reused in other APIs without the need to write them again.

· Integration Zone
Free Resource

Modernize your application architectures with microservices and APIs with best practices from this free virtual summit series. Brought to you in partnership with CA Technologies.

RAML, the language for modeling RESTful APIs has reached version 1.0. As we know, RAML was created to improve and enhance the way that APIs are provided.

There are several changes in this release compared to RAML 0.8:

  • Data types.

  • Examples.

  • Annotations.

  • Libraries.

  • Overlays and extensions.

  • Improved security schemes.

Here's a simple example of what a RAML 1.0 file looks like:

#%RAML 1.0
title: Brochure
version: v1
baseUri: http://localhost:8080
protocols: HTTP
mediaType: application/json
types:
  ModelTree:
    type: object
    properties:
      modelTreeReference: string
      brand: string
      series?: string
      constructionSeries?: string
      bodyType?: string
      AGModelCode?: string
      UKModelCode?: string
      levelCode?: number
  Brochure:
    type: object
    properties:
      recordNumber: number
      partNumber: number
      name: string
      brand: string
      brochureType: string
      CRMGroup: string
      CRMSubGroup: string
      isActiveIndicator: string
      modelTree: ModelTree
  Status:
    type: object
    properties:
      responseStatus:
        enum: [COMPLETE, ERROR, FATAL]
      responseId: number
  Transaction:
    type: object
    properties:
      status: Status
      data:
        type: object
        properties:
          brochures?: Brochure[]
/brochures:
  get:
    responses:
      200:
        description: Status and a list of Brochures
        body:
          application/json:
            example: {
              status: {
                responseStatus: 'COMPLETE',
                responseId: 123
                },
              data: {
                brochures: [{
                    recordNumber: 1,
                    partNumber: 56,
                    name: "Activity Brochure",
                    brand: "My Brand Ltd",
                    brochureType: "HARDCOPY",
                    CRMGroup: "Sales",
                    CRMSubGroup: "Lifestyle/Access",
                    isActiveIndicator: "N",
                    modelTree: {
                      modelTreeReference: "My Brand",
                      brand: "My Brand Ltd",
                      levelCode: 1
                      }
                  }
                ]
                }
              }
            type: Transaction

Data types are probably the most important feature introduced in this release. Taken from object-oriented programming languages like Java, data types allow the user to define objects and reuse them at any level in a RAML file.

Taken from the previous example, ModelTree is an example of a data type:

types:
  ModelTree:
    type: object
    properties:
      modelTreeReference: string
      brand: string
      series?: string
      constructionSeries?: string
      bodyType?: string
      AGModelCode?: string
      UKModelCode?: string
      levelCode?: number

This data type defines multiple properties, each of which is declared as a built-in type like string or number.

In a RAML file, we can define simple and complex data types.

Let's have a look at the following example:

#%RAML 1.0
title: Brochure
version: v1
baseUri: http://localhost:8080
protocols: HTTP
mediaType: application/json
types:
  ModelTree:
    type: object
    properties:
      modelTreeReference: string
      brand: string
      series?: string
      constructionSeries?: string
      bodyType?: string
      AGModelCode?: string
      UKModelCode?: string
      levelCode?: number
  Brochure:
    type: object
    properties:
      recordNumber: number
      partNumber: number
      name: string
      brand: string
      brochureType: string
      CRMGroup: string
      CRMSubGroup: string
      isActiveIndicator: string
      modelTree: ModelTree
  Status:
    type: object
    properties:
      responseStatus:
        enum: [COMPLETE, ERROR, FATAL]
      responseId: number
  Transaction:
    type: object
    properties:
      status: Status
      data:
        type: object
        properties:
          brochures?: Brochure[]

Some properties are defined as data types. For example, the property modelTree in the type Brochure is a ModelTree data type.

According to the RAML specs, RAML types can be summarized as follows:

  • Types are similar to Java classes.

  • Multiple inheritance is allowed.

  • Types can be split into four families: externalobjectarray, and scalar .

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

  • Properties are regular object-oriented properties.

  • Facets are special configurations.

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

The node types in the root of the document will start the data types declaration. Once the data type has been declared, an object type should be defined for it:

Brochure:
    type: object

You can also define some facets, like in the following code, which gives an example of that data type:

Brochure:
    type: object
    example: {
          recordNumber: 1,
          partNumber: 56,
          name: "Activity Brochure",
          brand: "My Brand Ltd",
          brochureType: "HARDCOPY",
          CRMGroup: "Sales",
          CRMSubGroup: "Lifestyle/Access",
          isActiveIndicator: "N",
          modelTree: {
            modelTreeReference: "My Brand",
            brand: "My Brand Ltd",
            levelCode: 1
            }
        }

There are several available facets that depend on the chosen type. For instance, for an object type, we could have properties, minPoperties, maxPoperties, additionalProperties, discriminator, or discriminatorValue.

An example of the properties facet can be declared for this data type:

  Brochure:
    type: object
    properties:
      recordNumber: number
      partNumber: number
      name: string
      brand: string
      brochureType: string
      CRMGroup: string
      CRMSubGroup: string
      isActiveIndicator: string
      modelTree: ModelTree

A property might have the required facet, which could be declared in two ways. Like this...

   Brochure:
    type: object
    properties:
      recordNumber:
      required: true
  type: number

...or like this:

  Brochure:
    type: object
    properties:
      recordNumber?: number

Multiple inheritance is allowed in RAML:

types:
  Person:
    type: object
    properties:
      name: string
  Employee:
    type: object
    properties:
      employeeNr: integer
  Manager:
    type: [ Person, Employee ]

This means that Manager will inherit all the restrictions from Person and Employee types.

In RAML, it's possible to organize APIs in a more readable way by using of libraries.

The data types can be put in a new RAML file like this:

#%RAML 1.0 Library
# this file is located at libraries/my_types.raml
types:
  ModelTree:
    type: object
    properties:
      modelTreeReference: string
      brand: string
      series?: string
      constructionSeries?: string
      bodyType?: string
      AGModelCode?: string
      UKModelCode?: string
      levelCode?: number
  Brochure:
      type: object
      example: {
              recordNumber: 1,
              partNumber: 56,
              name: "Activity Brochure",
              brand: "My Brand Ltd",
              brochureType: "HARDCOPY",
              CRMGroup: "Sales",
              CRMSubGroup: "Lifestyle/Access",
              isActiveIndicator: "N",
              modelTree: {
                modelTreeReference: "My Brand",
                brand: "My Brand Ltd",
                levelCode: 1
                }
            }
      properties:
          recordNumber: number
          partNumber: number
          name: string
          brand: string
          brochureType: string
          CRMGroup: string
          CRMSubGroup: string
          isActiveIndicator: string
          modelTree: ModelTree
  Error:
      type: object
      properties:
          errorCode: string
          errorDescription: string
  Status:
      type: object
      properties:
          responseStatus:
            enum: [COMPLETE, ERROR, FATAL]
          responseId: number
  Transaction:
    type: object
    properties:
        status: Status
        data:
          type: object
          properties:
            brochures?: Brochure[]
            errors?: Error[]

Pay attention to the Library keyword in the first line. You are telling RAML that this is going to be a library file.

Then we can use the node uses to import external libraries:

uses:
  file-types: libraries\my_types.raml

This means that we are referencing my_types.raml with the name file-types.

Data types will be accessible using the dot notation, i.e., file-types.Transaction.

We can also put JSON examples in external files. For instance, we might create examples for response with the 200 status code and one for 400.

examples/200.json:

{
  "status": {
    "responseStatus": "COMPLETE",
    "responseId": 123
    },
  "data": {
    "brochures": [{
        "recordNumber": 1,
        "partNumber": 56,
        "name": "Activity Brochure",
        "brand": "My Brand Ltd",
        "brochureType": "HARDCOPY",
        "CRMGroup": "Sales",
        "CRMSubGroup": "Lifestyle/Access",
        "isActiveIndicator": "N",
        "modelTree": {
          "modelTreeReference": "My Brand",
          "brand": "My Brand Ltd",
          "levelCode": 1
          }
      }]
    }
}

examples/400.json:

{
  "status": {
    "responseStatus": "FATAL",
    "responseId": 123
    },
  "data": {
    "errors": [{
      "errorCode": "ERROR-123",
      "errorDescription": "Duplicate requestUUID"
    }]
    }
}

Then, we can import these examples with the !include keyword.

Wrapping up a complete example, we would have:

#%RAML 1.0
title: Brochure
version: v1
baseUri: http://localhost:8080
protocols: HTTP
mediaType: application/json
uses:
  file-types: libraries\my_types.raml
/brochures:
  get:
    responses:
      400:
        description: Status and a list of Errors
        body:
          application/json:
            example: !include examples\400.json
            type: file-types.Transaction
      200:
        description: Status and a list of Brochures
        body:
          application/json:
            example: !include examples\200.json
            type: file-types.Transaction

In this way, our API will be much more readable and the data types can be reused in other APIs without the need to write them again.

In the next article, we will go through resource types, annotations, and security schemes. 

This guide doesn't mean to be a complete guide to RAML 1.0 — it's mostly a tutorial and an overview of what we can achieve using RAML 1.0.

The Integration Zone is proudly sponsored by CA Technologies. Learn from expert microservices and API presentations at the Modernizing Application Architectures Virtual Summit Series.

Topics:
integration ,raml 1.0 ,tutorial ,restful apis

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}