DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Enhancing Business Decision-Making Through Advanced Data Visualization Techniques
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • Building an AI/ML Data Lake With Apache Iceberg
  • Beyond Simple Responses: Building Truly Conversational LLM Chatbots

Trending

  • Next-Gen IoT Performance Depends on Advanced Power Management ICs
  • AI Speaks for the World... But Whose Humanity Does It Learn From?
  • Event-Driven Microservices: How Kafka and RabbitMQ Power Scalable Systems
  • Distributed Consensus: Paxos vs. Raft and Modern Implementations
  1. DZone
  2. Data Engineering
  3. Data
  4. An Overview of RAML 1.0

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.

By 
Giuseppe D'Elia user avatar
Giuseppe D'Elia
·
Mar. 15, 17 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
43.0K Views

Join the DZone community and get the full member experience.

Join For Free

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: external, object, array, 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.

Data (computing)

Opinions expressed by DZone contributors are their own.

Related

  • Enhancing Business Decision-Making Through Advanced Data Visualization Techniques
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • Building an AI/ML Data Lake With Apache Iceberg
  • Beyond Simple Responses: Building Truly Conversational LLM Chatbots

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: