register
other register

Monday, August 04, 2008

REST with Grails

Please refer to Grails Documentations for more info on REST with Grails. 

1. Create a grails project grails create-app rest 
2. Create a domain class with name Book 
create domain-class Book

class Book { 
String title 
String publisher 

3. Use generate-all to generate views and controller 

grails generate-all Book 

4. Modify Bootstrap.groovy to add sample data.
class BootStrap {      
 def init = { servletContext ->          
 new Book(title:"game1",publisher:"pub1").save()         
 new Book(title:"game2",publisher:"pub1").save()          
 new Book(title:"game3",publisher:"pub2").save()          
 new Book(title:"game4",publisher:"pub2").save()      
}      
def destroy = {      } }    

5. Modify UrlMappings.groovy  
 static mappings = {    
  "/book/$id?"(controller:"book"){        
   action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]    
  }  
 }  
6. Modify BookController.groovy show method
import grails.converters.* class BookController {  
 def show = {   
  if(params.id && Book.exists(params.id)) {    
   def b = Book.get(params.id)    
   render b as XML   
  }   
  else {    
   def all = Product.list()    
   render all as XML   
  }  
 }  
 .. 
}   
The method can be tested with this showTest.groovy client   
import org.apache.commons.httpclient.*; 
import org.apache.commons.httpclient.methods.*; 
def url = "http://localhost:8080/rest/book/${args[0]}" 
def method = new GetMethod(url)    
// Require HTTPClient library 
def client = new HttpClient() 
def statusCode = client.executeMethod(method) 
println "STATUS CODE:$statusCode" 
def stream = method.getResponseBodyAsStream() 
println "--- START RESPONSE BODY --- " 
System.out << stream println "n--- END RESPONSE BODY ---" 
stream.close() method.releaseConnection()  

Notes: You need to put Apache Commons Codec, and HTTPClient jars in the $GROOVY_HOMElib    

7. Modify BookController.groovy save method  
def save = {     
 def book = new Book(params['book'])     
 if(book.save())         
  render book as XML     
 else{         
  def myerrors = game.errors.allErrors.collect { 
   g.message(error:it) 
  }         
  render(contentType:"text/xml") {             
   errors {                 
    for(err in myerrors) {                     
     error(err)                 
    }             
   }         
  }     
 }         
}  

You can test the method with the client saveTest.groovy below:  

import org.apache.commons.httpclient.*; 
import org.apache.commons.httpclient.methods.*; 
def url = "http://localhost:8080/rest/game" 
def method = new PostMethod(url) 
def client = new HttpClient() 
def payload = """ <book>   
<title>newgame</title>   
<publisher>
newpublisher</publisher> 
</book> 
""" method.addRequestHeader("Content-Type","text/xml") method.addRequestHeader("Accept","text/xml,application/xml;q=0.9") method.setRequestEntity(new StringRequestEntity(payload)) def statusCode = client.executeMethod(method) println "STATUS CODE:$statusCode" def stream = method.getResponseBodyAsStream() println "--- START RESPONSE BODY --- " System.out << stream println "n--- END RESPONSE BODY ---" stream.close() method.releaseConnection() 

No comments: