4
votes

I'm trying to create a RESTful controller in Grails 2.3.4. I am following the documentation exactly, however, any time I try to POST, I always hit the index method. The only way I can get save() to work is to delete the index method. This doesn't make any sense to me.

I have tried both extending the RestfulController superclass: http://grails.org/doc/2.3.4/guide/webServices.html#extendingRestfulController

And implementing my own methods: http://grails.org/doc/2.3.4/guide/webServices.html#restControllersStepByStep

And yet, when I post to my url, it only hits the index method, whether it's the one in the RestfulController I'm extending, or in my own method.

I have "/api/lab"(controller: "lab") in UrlMappings.groovy I have json: ['application/json', 'text/json'], defined in my mime types

I've tried adding and removing static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"] from my controller.

But no matter what I do, I cannot seem to hit save().

This is my controller when I am implementing my own controller:

class LabController {
static responseFormats = ['json']

def userService

def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    Patient patient = userService.currentUser.patient
    render PatientLab.findAllByPatientAndType(patient, LabType.findByName(LabType.LAB_TYPE_INR)) as JSON
}

@Transactional
def save() {
    Patient patient = userService.currentUser.patient
    LabType inrType = LabType.findByName(LabType.LAB_TYPE_INR)

    boolean labAlreadyExists = PatientLab.findByPatientAndLabDateAndType(patient, request.JSON.labDate, inrType)

    if (labAlreadyExists) {
        render {result: "Lab already exists"} as JSON
        return
    }

    PatientLab patientLab = new PatientLab()
    patientLab.patient = patient
    patientLab.origin = LabOrigin.MOBILE_APP
    patientLab.type = inrType
    patientLab.result = request.JSON.result
    patientLab.measurement = UnitType.findByUnit(UnitType.UNIT_TYPE_NONE)
    patientLab.labDate = new Date()

}
}

This is my controller when extending RestfulController:

class LabController extends RestfulController {
static responseFormats = ['json']

LabController() {
    super(PatientLab)
}
}
1

1 Answers

4
votes

So the allowedMethods is just going to stop you from getting a GET request to save(), what you really want is the Restful Mappings so instead of mapping with

"/api/lab"(controller: "lab")

Use

"/api/labs"(resources: "lab")

That will map your POST to /api/labs to the save() method. If you don't want to use plurals in your rest controller you can use resource instead but I most of the time go with plurals. I like to have a list of which methods I am supporting and I do that with includes:['index', 'show'] allowing me to easily support just a few operations.