1
votes

When following http://grails.org/doc/latest/guide/webServices.html#restfulControllers in order to create RESTful webservices, I am getting 404 error when I hit anything other than index.

in my Bootstrap.groovy I have

def init = { servletContext ->
    new Restaurant(title:"mourne seafood").save()
    new Restaurant(title:"RBG").save()
}

in my Restaurant.groovy domain class i have

 class Restaurant {

    String title

    static constraints = {
    }
}

and in my RestaurantController.groovy REST controller I have

import grails.rest.*;

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

I thought when reading the above link that if I call GET <domain>/restaurant It would call the index method, which is fine, this works, however when I call GET <domain>/restaurant/1 I thought it should call the show method with 1 as the id? However I am getting a 404. It works correctly when I hit GET <domain>/restaurant/show/2 am I wrong in thinking that when the docs say

GET /books/${id} show in the mapping table that I shouldnt have to explicitly put show in the URL?

1
What is <domain>/restaurant? The url in Grails is application/controller/action/id - user800014
domain being application. Restaurant is the controller - andy mccullough

1 Answers

0
votes

I know It sucks but here it is:

You need to create a generic rest controller and annotate the domain class pointing to it.

First delete the RestaurantController.groovy

Then create a BaseRestController (inside the src/main/groovy folder)

src/main/groovy/BaseRestController.groovy

import grails.rest.*;

class BaseRestController<T> extends RestfulController<T> {

    BaseRestController(Class<T> domainClass) {
        this(domainClass, false)
    }
    BaseRestController(Class<T> domainClass, boolean readOnly) {
        super(domainClass, readOnly)
    }

    @Override
    def show() {
        println 'showing...'
        respond queryForResource(params.id)
    }
}

Ps. I just override the index action to show it works Now you can annotate the domain class

grails-app/domain/Restaurant.groovy

import grails.rest.*
@Resource(uri='/restaurants', formats=['json', 'xml'], superClass=BaseRestController)
class Restaurant {

    String title

    static constraints = {
    }
}

You need to specify the formats in the domain class and not in the controller. Otherwise it will be ignored and XML will be default. I named the api endpoint as restaurants instead of the grails default restaurant Now you can HTTP your RestFull app e.g. http://localhost:8080/restaurants/1