Reading Time: 13 minutes

In this blog, we will see how to design a REST API using the Restful API Modeling language. It’s important to design the APIs before we actually implement it and get the feedback from architects, users, or business stakeholders. It gives us an advantage during the design phase to modify the API which includes request messages, response messages, headers, or query params, etc.

API design is always the first step in building the applications. It is important to define the right resources, request and response models, headers, query parameters, error codes, and methods to design a robust API. This approach is also known as a design-first approach.

What is RESTful API Modeling language?

RESTful API Modeling language is an API design language that allows developers to take advantage of the full API design lifecycle, meaning that they can visually design their APIs, test them, and get user feedback without ever having to write a single line of code. RESTful API Modeling language describes APIs in a human readable format — plain text.

RESTful API Modeling Language is a YAML-based language for describing RESTful APIs. It provides all the information necessary to describe RESTful or practically RESTful APIs. 

RESTful API Modeling language is capable of describing APIs that do not obey all constraints of REST (hence the description “practically RESTful”). It encourages reuse, enables discovery, and pattern-sharing and aims for merit-based emergence of best practices.

Here we will consider the use case related to banking APIs and writing the RESTful API Modeling language:

  • List all the accounts for customers (GET/accounts)
  • List single account (GET/accounts/{accountId})
  • Create account (POST/accounts)
  • List the balance for account (GET/accounts/{accountId}/balances)
  • List all transactions for account and filter on basis of date range (GET /accounts/{accountId}/transactions?fromTransactionDate=2021-07-01&toTransactionDate=2021-08-01)
  • List single transaction for account (GET /accounts/{accountId}/transactions/{transactionId})
latest report
Learn why we are the Leaders in API management and iPaaS

Root

In RESTful API Modeling language, we need to define the root with some basic information like title, version, baseUri, protocols, and media type supported by APIs.

#%RAML 1.0
title: Open Banking API
version: v1
baseUri: http://api.openbanking.com/{version}
 
protocols:
  - HTTP
  - HTTPS
 
mediaType: 
  - application/json
  - application/xml

Below is the description about the root attributes that we have declared in above code:

  • API titles: The title of the API should be a short, plain-text label for the API.
  • Version: Each API should have a corresponding alphanumeric version.
  • Protocols: The optional protocols node specifies the protocols that an API supports. If the protocol node is not explicitly specified, the protocol in the baseUri node is used.

As a best practice, it is important to define the title, version, baseUri, mediaType, and protocols at root level. RESTful API Modeling language file names are in lowercase, alphanumeric characters using kebab-case (i.e. hyphen-separated).

Resources

This is one of the important steps where you need to define your API resources and resources begin with (/). Using the resources, you are controlling how the APIs will be consumed by the consumers or clients. 

Resources enclosed in the curly brackets is an uri parameter. URI parameter (Path Param) is basically used to identify a specific resource or resources.

As best practices, Resource name must always be plural and also it should be a noun not a verb.

/accounts:
  /{accountId}:
    /balances:
    /transactions:
      /{transactionId}:

Methods

There are various HTTP methods supported by REST APIs and are listed below:

  • GET: Fetch the information from the server
  • POST: Create the resources on the server
  • DELETE: Remove the resources from the server
  • PUT: Create or update the new or existing resources on server
  • PATCH: Modify the resources on the server

We can define the methods for each resource and there can be more than one http method for each resource.

APIs should only provide nouns for resources and let the HTTP verbs (GET, POST, PUT, DELETE) define the action to be performed on a resource. Use POST, DELETE or PUT instead of GET to alter the state. ​Do Not use GET to alter the changes. ​

/accounts:
  get:
  post:
  /{accountId}:
    get:
    /balances:
      get:
    /transactions:
      get:
      /{transactionId}:
        get:

We have defined the appropriate method for our resource depending on the use case.

Defining header and query parameters

Query parameter is basically used to filter or sort the resources. It is passed in the URL as a query string in key-value form.

In our use case, we need to fetch the transaction and they can be filtered on the basis of date range. We will be using fromDate and toDate as query parameters for filtering the transactions.

Use query parameters defined in the URL for filtering a resource from the server. 

/accounts:
  get:
    headers:
      customerId:
        required: true
        type: string
        example: "323232"
        maxLength: 20
  post:
  /{accountId}:
    get:
    /balances:
      get:
    /transactions:
      get:
      /{transactionId}:
        get:
          queryParameters:
            fromTransactionDate:
              type: date-only
              example: "2021-08-01"
              required: false
            toTransactionDate:
              type: date-only
              example: "2021-08-20"
              required: false

We need to fetch all accounts for particular customers. In this case, we will be using customerId as header parameter for fetching account details for particular customers. We would have been using customerId as a query parameter but it is sensitive information so we can pass it in the header.

Request and responses

We need to map responses with one or more HTTP status codes. Response can be defined in RAML in the form of Schemes, Examples, types or descriptions.

/accounts:
  get:
    description: Fetch all the accounts for customers.
    headers:
      customerId:
        required: true
        type: string
        example: "323232"
        maxLength: 20
    responses:
      200:
       body:
        application/json:
          example: |
            [{
              "accountId": "32323232",
              "accountType": "Current",
              "accountName": "Mr. James John",
              "currency": "USD",
              "status": "Active"
            }]

In the above RAML, we have defined the response for success http status code 200 but we can also define the response for error http status code like 404, 500 as shown below.

/accounts:
  get:
    description: Fetch all the accounts for customers.
    headers:
      customerId:
        required: true
        type: string
        example: "323232"
        maxLength: 20
    responses:
      200:
       body:
        application/json:
          example: |
            [{
              "accountId": "32323232",
              "accountType": "Current",
              "accountName": "Mr. James John",
              "currency": "USD",
              "status": "Active"
            }]
      404:
        body:
          application/json:
            example: {"message": "Resource Not Found", "errorCode": "404"}
      500:
        body:
          application/json:
            example: {"message": "Internal Server Error", "errorCode": "500"}

Request is generally used when we need to pass body to API request and it is generally used with POST, PUT, PATCH method where we can create or modify the resources on the server.

/accounts:
  get:
    description: Fetch all the accounts for customers.
    headers:
      customerId:
        required: true
        type: string
        example: "323232"
        maxLength: 20
    responses:
      200:
       body:
        application/json:
          example: |
            [{
              "accountId": "32323232",
              "accountType": "Current",
              "accountName": "Mr. James John",
              "currency": "USD",
              "status": "Active"
            }]
      404:
        body:
          application/json:
            example: {"message": "Resource Not Found", "errorCode": "404"}
      500:
        body:
          application/json:
            example: {"message": "Internal Server Error", "errorCode": "500"}/accounts:
  get:
    description: Fetch all the accounts for customers.
    headers:
      customerId:
        required: true
        type: string
        example: "323232"
        maxLength: 20
    responses:
      200:
       body:
        application/json:
          example: |
            [{
              "accountId": "32323232",
              "accountType": "Current",
              "accountName": "Mr. James John",
              "currency": "USD",
              "status": "Active"
            }]
      404:
        body:
          application/json:
            example: {"message": "Resource Not Found", "errorCode": "404"}
      500:
        body:
          application/json:
            example: {"message": "Internal Server Error", "errorCode": "500"}
  post:
    description: Create Account for customer.
    body:
      application/json:
        example: |
          [{
            "customerId": "6327632",
            "accountId": "32323232",
            "accountType": "Current",
            "accountName": "Mr. James John",
            "currency": "USD"
          }]
    responses:
      200:
        body:
          application/json:
            example: {"message": "Account Added Successfully"}

Summary

In this RAML 101, we have seen how to define the basic RAML with resources, request, responses, URI Parameters, Query Parameters, etc. If you notice for all the methods, the pattern remains the  same but only the response example is different for each method. There is a possibility to avoid writing similar patterns and code for each method. In our RAML 201, we will see how to promote code reusability and better readability using resource types, library, traits, etc. 

To learn more about RESTful API Modeling language, you can watch the recording session from the recent Surat MuleSoft meetup.

Jitendra Bafna is one of our MuleSoft Ambassadors, you can find him on LinkedIn.

Series NavigationHow to improve code readability and reuse with RAML >>