facebook
Srivatsan Sundararajan
Senior Manager, QA for MyEclipse, DevStyle and CodeTogether.
Posted on Jan 4th 2016

What is RAML?

RAML stands for RESTful API Modeling Language. It is a YAML based language for defining RESTful APIs and contains all the necessary information to describe RESTful APIs. YAML is a data serialization language that is easier to read and understand than other formats like XML or JSON. More details on RAML and its usage can be found at raml.org.

RAML API Specification

The RAML specification provides all the information necessary to describe RESTful APIs. RAML documents support all YAML features. RAML also enables documentation generator tools to extract the user documentation and translate it to visual formats such as HTML or PDF. RAML introduces the concept of resource types and traits characterizing resources and methods, thereby minimizing repetition in a RESTful API’s design.

Use Case

This article walks you through building a blogging system. The system includes the following requirements:
  • Display full list of posts.
  • Display full list of authors and the posts authored by them.
  • Display comments by readers on each post.
  • Authors can create new posts, modify or delete existing posts.
  • Readers can view and can comment on posts.
  • Authors can moderate comments.
  • Posts and authors are paginated, searchable and sortable.
  • Comments are paginated and sortable.
  • Search for a post by post title and author name.
  • Show a particular author’s post(s).
  • Show a particular reader’s comment(s).
  • View a post.
diagrams-united

Creating the RAML File

If you are using MyEclipse or Webclipse, select File> New>Other>General>File to create a new RAML file with the name MyBlog.raml. The newly created file opens in the RAML Editor.

1. Add the Document Root

In the root section let’s add the basic information of the API, such as its title and base URI, protocols, media type, schemas, version, etc. of the api. For our example, we will implement title, baseUri and version.
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1
title (required)—The title property is a short plain text description of the RESTful API. baseUri (optional during development, required after implementation)—The use of the baseUri field is optional to allow describing APIs that have not yet been implemented. After the API is implemented (even a mock implementation) and can be accessed at a service endpoint, the API definition must contain a baseUri property. version (optional)—If the RAML API definition is targeted to a specific API version, the API definition must contain a version.

2. Add Resources

This is the most fundamental element in RAML since the entire API implementation is around resources. A resource defined at the root level is called a top-level resource. A resource which is defined as a child of another resource is called a nested resource. For our example, let’s begin by creating a top-level resource named posts.
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1

/posts:
Resources have to be preceded by a forward slash (/) and end with a colon (:). Any methods and parameters nested under these top level resources belong to and act upon that resource. The post resource defined above is accessible at http://myblog.com/v1/posts. Notice that the final URL to the resource is based on the information provided in the document root section.

3. Add Nested Resources

For our blogging system, let’s add some nested resources. Nested resources are useful when you want to call out a particular subset of your resource in order to narrow it.
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1

/posts:
  /authors:
  /readers:
  /comments:
Similar to the root resource, nested resources can be accessed using http://myblog.com/v1/posts/authors. Even if the API has several nested resources defined, they can be easily accessed with the URL similar to the above making it very easy for the API developers and consumers to access any nested resource.

4. Add Methods

The most common HTTP methods are: GET—Retrieve the information defined in the request URI. PUT—Replace the addressed collection. At the object-level, create or update it. POST—Create a new entry in the collection. This method is generally not used at the object-level. DELETE—Delete the information defined in the request URI. In our example, the API consumers can retrieve a post from the list of posts (GET), create a new blog post (POST), update an existing blog post (PUT), add a new comment (POST), modify existing comments (PUT), or delete posts and/or comments (DELETE). Add the methods to the root resource (post) as follows:
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1

/posts:
  /authors:
  /readers:
  /comments:
    
  get:
  post:
  put:
  delete:

5. Add URI Parameters

The root resource is made of nested resources. Resources are made of individual resources. That is, posts is made up of individual posts, authors is made up of individual authors, etc. Such individual resources can be accessed via the URI parameters. URI parameters are denoted by surrounding curly braces {} in RAML; for example, {title} for posts, {authorName} for authors, etc. Let’s add the URI parameters for our resources as follows:
/posts:
  /{id}:
  /{title}:
  /{content}:
	/{post}:
  	/{id}:
  	 
	/{author}:
  	/{id}:
  	/{authorName}:
  	 
  /authors:
	/{id}:
	/{authorName}:
 	 
  /readers:
	/{id}:
	/{readername}:
	/{commentid}:
 	 
  /comments:
	/{commentid}:
To access an individual post, say post with id=1, the URL is http://myblog.com/v1/posts/1. This type of referencing is also applicable to individual nested resources.

6. Add Query Parameters

Thus far we have defined collection based resource types that are further defined by object based URI parameters. To perform additional operations like filtering on these two, we need to define query parameters. We define query parameters similar to URI parameters. Query parameters are a mixture of meta information like description, access_tokens (required by server), whether required or not. Query parameters may be defined on any number of nested resources and their methods.
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1

/posts:
  /authors:
  /readers:
  /comments:
    
 get:
	queryParameters:
  	 id:
    	  type: Integer
    	  description: The id of the post
    	  required: true
  	 title:
    	  type: String
     	  description: The title of the post
    	  required: true
  	 author:
    	  type: String
    	  description: The author of the post
    	  required: true
  	 date:
    	  type: Date
    	  description: The date of creation of the post
  post:
	
	queryParameters:
  	 access_token:
    	  type: string
    	  description: Access Token
    	  required: true
  put:
	
	queryParameters:
  	 access_token:
    	  type: string
    	  description: Access Token
    	  required: true
  delete:
	
	queryParameters:
  	 id:
    	  type: String
    	  description: The title of the post
    	  required: true
  	 title:
    	  type: String
    	  description: The title of the post
    	  required: true
  	 author:
    	  type: String
    	  description: The author of the post
    	  required: true
  	 date:
    	  type: Date
    	  description: The date of creation of the post
Now, let’s add query parameters for all our nested resources like the ones shown in the following example. Refer to the sample file to view all nested resources that require query parameters.
#%RAML 0.8
title: MyBlog RAML
baseUri: http://myblog.com/{version}
version: v1

/posts:
 
  /{id}:
	get:
  	queryParameters:
    	id:
      	type: Integer
      	description: The id of the post
      	required: true
 	 
	delete:
  	queryParameters:
    	id:
      	type: Integer
      	description: The id of the post
      	required: true
  /{title}:
    
	get:
  	queryParameters:
    	title:
      	type: String
      	description: Get post by title
      	required: true
	delete:
  	queryParameters:
    	title:
      	type: String
      	description: Get post by title
      	required: true

7. Define Responses

Now that we have defined resources and available methods, we need to describe the responses a user can expect. Responses may include descriptions, examples, or schemas. Responses are defined like below.
/posts:
  
  /{id}:
	get:
  	queryParameters:
    	id:
      	type: Integer
      	description: The id of the post
      	required: true
  	responses:
    	200:
      	body:
        	application/json:
          	example: |
             	{
               	"data": {
                 	"id": "postID",
                 	"title": "My Post",
                 	"author": "Foo",
                 	"date": 1341533193,
                 	"content": "Sample content",
               	},
               	"success": true,
               	"status": 200
             	}
        	application/xml:	

8. Define Traits

In your RAML API, there may be some behaviors, policies or characteristics that are common across different resources, for example search or pagination. Such behavior can be handled easily with traits. Traits are typically defined at the beginning of the RAML spec and can be used anywhere within the RAML. For our API, let’s define 4 traits: secured, searchable, paged and orderable.
traits:
  - secured:
  	usage: Apply this to any method that needs to be secured
  	description: Some requests require authentication.
  	queryParameters:
    	access_token:
      	description: Access Token
      	type: string
      	example: ACCESS_TOKEN
      	required: true
  - searchable:
  	usage: Apply this to enable search support
  	description: Blog can be searched for posts, authors.
  	queryParameters:
    	query:
      	description: search query
      	type: string
  - paged:
  	usage: Apply this to any method that produces results and requires pagination
  	description: Some requests require authentication.
  	queryParameters:
   	start:
     	description: The first page to return
     	type: number
   	pages:
     	description: The number of pages to return
     	type: number
  - orderable:
  	usage: Apply this to any method that produces results and requires ordering in any format
  	description: Some requests require authentication.
  	queryParameters:
    	orderBy:
      	description: Test
      	type: string
      	required: false
    	order:
      	description: Order
      	enum: [desc, asc]
      	default: desc
      	required: false
Traits can be used across resources like below:
/posts:
  is: [searchable]
  /{id}:
	get:
  	queryParameters:
    	id:
 
 /{authorName}:
  	is: [searchable, paged, orderable]
  	get:
    	queryParameters:
You can copy the following attachment into an existing project to get a look at the completed RAML file with all of the traits. Congratulations, you now know how to write an API definition in RAML!

RAML/YAML Support in Eclipse

If you’re looking for RAML/YAML support in Eclipse, you can use either MyEclipse or Webclipse which installs into your existing Eclipse IDE. Here are a few screenshots covering this feature set in Webclipse. RAMLEditor The Editor includes syntax coloring, default formatting and syntax validation.   RAMLOutline Use the Outline view for a nice overview of the file and to quickly locate errors.   YAMLPreferences Easily customize the Editor to your liking.  

Let Us Hear from You!

If you have any comments or questions, we would love to hear from you @MyEclipseIDE on twitter or via the MyEclipse forum.