Create a REST API with Grails 2.3.x in 15 Minutes (Part 1)

Grails 2.3 received quite a lot powerful improvements. Here I will make use of two of them:

What I want to do is to create with minimal efforts a Grails 2.3.x REST service, which exposes some city data via a REST API:

http://localhost/RESTService/api/city

The REST service should respond either as json or xml depending on the request header.

[{
"id":1,
"cityName":"Munich",
"countryCode":"DE",
"postalCode":"81927"
}]

With the new Grails 2.3 this could be done in nearly 15 minutes. So let’s start the timing!

Create the Grails Project

grails create-app RESTService

Create the Domain Class

package com.jolorenz.rest

import groovy.transform.ToString
import groovy.transform.EqualsAndHashCode

/**
 * City
 * A domain class describes the data object and it's mapping to the database
 */

@ToString(includeNames = true, includeFields = true, excludes = 'dateCreated,lastUpdated,metaClass')
@EqualsAndHashCode
class City {

	/* Default (injected) attributes of GORM */
	Long	id
	Long	version

	/* Automatic timestamping of GORM */
	Date	dateCreated
	Date	lastUpdated
	
	
	String cityName
	String postalCode
	String countryCode // either iso2 or iso3

	static constraints = {
		postalCode blank:false, nullable:false
		cityName blank:false, nullable:false
		countryCode minSize:2, maxSize:3, blank:false, nullable:false, matches: "[A-Z]+"
	}
}

Add Data into the Database

Modify /conf/BootStrap.groovy to get some data inserted into your City DB:


import com.jolorenz.rest.City
import grails.util.Environment

class BootStrap {
	def init = { servletContext ->

		def result = '################## running in UNCLEAR mode.'
		println "Application starting ... "
		switch (Environment.current) {
			case Environment.DEVELOPMENT:
				result = 'now running in DEV mode.'
				seedTestData()
				break;
			case Environment.TEST:
				result = 'now running in TEST mode.'
				break;
			case Environment.PRODUCTION:
				result = 'now running in PROD mode.'
				seedProdData()
				break;
		}
		println "current environment: $Environment.current"
		println "$result"
	}
	
	def destroy = {
		println "Application shutting down... "
		}

	private void seedTestData() {
		def city = null
		println "Start loading cities into database"
		city = new City(cityName: 'Munich', postalCode: "81927", countryCode: 'DE')
		assert city.save(failOnError:true, flush:true, insert: true)
		city.errors = null

		city = new City(cityName: 'Berlin', postalCode: "10115", countryCode: 'DE')
		assert city.save(failOnError:true, flush:true, insert: true)
		city.errors = null
		
		assert City.count == 2;
		println "Finished loading $City.count cities into database"
	}
}

Until now, the work was mostly preparatory and boiler plate coding. The more interesting part starts now and it is surprisingly small.

Create the RESTful Controller

Next, we need a RESTful controller, e.g. CityController.
The Grails documentation suggests to extend the grails.rest.RestfulController super class. This is super simple, so we take the source almost directly from the docs:

package com.jolorenz.rest

import grails.rest.RestfulController

class CityController extends RestfulController {
	static responseFormats = ['json', 'xml']
	CityController() {
		super(City)
	}
}

Run the REST Service

run: grails dev run-app RESTService and check your REST service:

$ curl -X GET -H "Accept:application/json" http://localhost:8080/RESTService/city

and the result is:

[{
  "class":"com.jolorenz.rest.City",
  "id":1,
  "cityName":"Munich",
  "countryCode":"DE",
  "dateCreated":"2014-02-28T03:48:12Z",
  "lastUpdated":"2014-02-28T03:48:12Z",
  "postalCode":"81927"
},{
  "class":"com.jolorenz.rest.City",
  "id":2,
  "cityName":"Berlin",
  "countryCode":"DE",
  "dateCreated":"2014-02-28T03:48:12Z",
  "lastUpdated":"2014-02-28T03:48:12Z",
  "postalCode":"10115"
}]

And if you want to get a xml response:

$ curl -X GET -H "Accept:application/xml" http://localhost:8080/RESTService/city
<?xml version="1.0" encoding="UTF-8"?>
<list>
   <city id="1">
      <cityName>Munich</cityName>
      <countryCode>DE</countryCode>
      <dateCreated>2014-02-28 04:48:12.82 MEZ</dateCreated>
      <lastUpdated>2014-02-28 04:48:12.82 MEZ</lastUpdated>
      <postalCode>81927</postalCode>
   </city>
   <city id="2">
      <cityName>Berlin</cityName>
      <countryCode>DE</countryCode>
      <dateCreated>2014-02-28 04:48:12.119 MEZ</dateCreated>
      <lastUpdated>2014-02-28 04:48:12.119 MEZ</lastUpdated>
      <postalCode>10115</postalCode>
   </city>
</list>

Pretty cool so far!

Add the APIs URL Mapping

Actually our service is responding to this url:

http://localhost:8080/RESTService/city

But as we want to provide an API, the url should resemble this in its name.
This is what I want:

http://localhost:8080/RESTService/api/city

To achieve this, /conf/UrlMappings.groovy needs to be modified:

class UrlMappings {

	static mappings = {
        "/$controller/$action?/$id?(.${format})?"{
            constraints {
                // apply constraints here
            }
        }

        "/"(view:"/index")
        "500"(view:'/error')
        //
        // RESTService api
        "/api/city"(resources: 'city')
   }
}

Restart your grails app and recheck with curl:

 curl -X GET -H "Accept:application/json" http://localhost:8080/RESTService/api/city

and you receive the json response:

[{
  "class":"com.jolorenz.rest.City",
  "id":1,
  "cityName":"Munich",
  "countryCode":"DE",
  "dateCreated":"2014-02-28T03:48:12Z",
  "lastUpdated":"2014-02-28T03:48:12Z",
  "postalCode":"81927"
},{
  "class":"com.jolorenz.rest.City",
  "id":2,
  "cityName":"Berlin",
  "countryCode":"DE",
  "dateCreated":"2014-02-28T03:48:12Z",
  "lastUpdated":"2014-02-28T03:48:12Z",
  "postalCode":"10115"
}]

Et voila, this is exactly what we wanted, just with a few lines of code.

Summary

What did we achieve?

  • We have a grails server up and running.
  • Added some data to a database.
  • Got a REST service up and running with its own uri and
  • the REST service responds either with an json or xml response.
  • Pretty cool!

    Our RESTService API is still very basic and lacks some important functionalities. Its use is completely open and not restricted by any security means. Also the response data is not limited. How to deal with these issues, I will come up in the next part.

    HTH Johannes

    Advertisements
    This entry was posted in Development, Grails and tagged , , . Bookmark the permalink.

    11 Responses to Create a REST API with Grails 2.3.x in 15 Minutes (Part 1)

    1. Pingback: Improve the REST Service API (Part 1) | Coding Snippets

    2. Pingback: Customize Properties from RESTful Responses and Improve the RESTService API (Part 3) | Coding Snippets

    3. Pingback: Logging HTTP Requests for better Debugging of the REST API (Part 4) | Coding Snippets

    4. veeseekay says:

      That did help. thanks

    5. BORN2CODE says:

      Reblogged this on nerd diaries and commented:
      Grails rest api

    6. LeoFaber says:

      Thanks for the tutorial, its really usefull. I have a question.. Is it really necessary a domain class? I have a controller that scrapes some informations from Wikipedia and i need to pass this json data to a main application throught a RESTful api (i need tuo apps cause the scraper doesnt work on the main app cause its grails version is too old) ..so Id like to have a simple controller in the scraper application that expose a RESTful method to the main application.. This method Will scrape the data and pass it to the main application.. So i dont need a domain class.. Is it possibile? Thanks in advance!

      • LeoFaber says:

        Ok.. the point is another.. I need to update the City domain class database when my RESTfull method is invoked.. How can i do that?
        Thanks..

    7. Pingback: Create a REST API with Grails 2.3.x in 15 Minutes (Part 1) | Johannes Lorenz – Coding Snippets | The Daily Kebab

    8. Mak says:

      This example does not work anymore, I have grails 2.3.7. Followed everything server is running but Curl or SOAPUI or POSTMan does not give any details.

    9. Mak says:

      Upgraded to JDK 1.8 and grails 3.0.4 and then the example works perfectly.

    10. Pedro says:

      Hi,

      Great tutorial. I would like to know if you could explain me how can I make a WS, just like yours, but receiving parameters.

      Thank you for your help and explanation.

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s