Back to Blog Archive

RAML code generation

Posted on: September 3, 2014
Author:
Justin C

Today we review some basic usage of a RAML code generator. RAML is a specification or model of a REST API. It basically allows you to describe your REST API using its constructs. These constructs describe your API at a high level and serve as a good reference or documentation for consumers of your API.

The rest of this blog post reviews a simple example of using a code generator for RAML. The idea being to take your RAML spec and pass it through this code generator to provide you with boilerplate code which is in line with the details specified in your RAML spec. There is no need to be fluent with RAML in order to follow along since the example is very basic, however, if you aren’t yet familiar with RAML specification syntax, the RAML tutorials are a good place to start. The specification for RAML itself can be found on Github.

The code generator used is this one; https://github.com/mulesoft/raml-jaxrs-codegen. Note that this artifact is not hosted on Maven central. However it is hosted here; http://nexus.openanalytics.eu/nexus/content/groups/public (thanks to David Dossot for pointing this out – this is actually a forked version of the project: https://github.com/openanalytics/raml-jaxrs-codegen).

So you have two options; either build and install the jars in your local maven repo or add the Open Analytics remote repository to the project (I have edited the repo for this example to use the latter approach).

If you’re taking the former approach and run into the following when building:

Failed to execute goal com.mycila.maven-license-plugin:maven-license-plugin:1.9.0:check (default) on project raml-jaxrs-codegen-parent: Some files do not have the expected license header

then you need to run mvn license:format which generates the license headers in the files which will keep the license plugin happy.

To follow along, clone the code for this blog post which is up on Github: https://github.com/ricston-git/blog-contacts-app

After cloning, you will have the following 3 directories: contacts-app, contacts-app-api, contacts-app-impl. You can build everything from contacts-app, which is the parent module for this application. So running maven commands from in there will target both contacts-app-api and contacts-app-impl. Contacts-app-api houses our RAML spec along with the generated code. Lets have a quick look at src/main/resources/raml/api.raml:

The first part of the spec is defining the format of certain JSON messages using JSON schema. I have included the exact name I want for the Java representation for each JSON schema in the “javaType” key. This is the only way I found of affecting the class names generated by the generator for this part of the RAML spec.

After the JSON schema definitions come the endpoint definitions. We’re only using one endpoint here – /contacts – which supports 3 operations:

  • GET /contacts
  • GET /contacts/{id}
  • POST /contacts

It should be fairly obvious that we can use these operations to get all contacts, get a particular contact, and create a new one. First thing worth mentioning is that the “displayName” key is used by the generator as the class name for your resources. If it’s omitted, then the name in the endpoint itself is used. For instance, API design considerations apart, if the endpoint were /favcontacts, omitting “displayName” will generate a Favcontacts interface. You could change this to FavContacts, for instance, by using the “displayName” (note that, design wise, an endpoint such as that would probably be better as /contacts/fav or /contacts?fav=true).

The rest of the RAML spec is pretty well described in the online specification link provided at the beginning of this post.

In order to kick off the code generation, you’ll need to package/compile/install the contacts-app-api (or the parent). If everything goes smoothly, you should be able to view the generated sources in contact-app-api/target/generated-sources/raml-jaxrs.

Contacts-app-impl is the module which actually implements contacts-app-api. Since this is just a demo, I have cut some corners and stubbed out the persistence aspect into: /contacts-app-impl/src/main/java/com/ricston/contacts/ds/DataStore.java

DataStore is injected (via Jersey’s HK2) into /contacts-app-impl/src/main/java/com/ricston/contacts/rest/impl/ContactsResource.java which is the main attraction in this module. ContactsResource implements the generated Contacts interface in contacts-app-api. Lets have a look at one of the implemented methods, the one behind GET /contacts:

The implementation is straightforward. We are simply retrieving all ApiContacts (no pagination) and returning the result as JSON with a status code of 200. Technically, we are not setting the Content-Type and status code ourselves. This is done by the generated code. We simply indicate when to return a jsonOk response and when to give back an internalServerError, the rest is handled by the code generated according to our RAML spec.

The rest of the implementation of our ContactsResource is just as straightforward. Note the use of plainInternalServerError in the postContacts method. As opposed to the previous internalServerError this one takes a String argument which is the plain text entity in our response to the client. This behaviour is made available to use by the addition of:

body:
text/plain:

to the 500 response in the post part of our /contacts RAML specification.

That pretty much covers the interesting aspects of ContactsResource.

Before leaving you to explore the example and RAML in general, note that there is a test driver in /contacts-app-impl/src/test/java/com/ricston/contacts/Main.java.

This basically starts up a Jetty server and deploys our REST API on it. You should be able to hit the server using some kind of client (e.g. curl, Chrome’s Postman, Firefox’s Poster etc…) to see the app in action.

Note; there are some interesting RAML-related projects you might want to have a look at here: http://raml.org/projects.html

For instance, raml2html is a nifty tool that generates a nice looking HTML page documenting your REST API based on your RAML spec. (You need to have Node and npm installed to use it).

The Api Designer is another handy tool you might want to check out. It allows you to validate your RAML spec as well as offer content assistance at different parts in you spec while editing it (do refer to the official spec if something you’re looking for is not suggested though as it might not be 100% comprehensive).

Hope you enjoyed this small guide to RAML code generation. Since it’s still in it’s early stages, the code generation project might need some playing around with, but considering the benefits, it is probably well worth your time!

Author:
Justin C

One Comment for “RAML code generation”

  1. Leo says:

    When I try to run this app, but i encountered an error

    java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;

    it is strange, if I using the https://github.com/jersey/jersey/tree/2.13/examples/helloworld-webapp sample project the configuration in the web.xml almost the same.

Leave a Reply to Leo

Contact Us

Ricston Ltd.
Triq G.F. Agius De Soldanis,
Birkirkara, BKR 4850,
Malta
MT: +356 2133 4457
UK: +44 (0)2071935107

Send our experts a message

Need Help?
Ask our Experts!