Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good Maintainable way to add a save method to grails service

I was looking at the sample pet clinic grails app on github.

It has a service for creating pets called PetclinicService that has a method for adding pets:

Pet createPet(String name, Date birthDate, long petTypeId, long ownerId) {
    def pet = new Pet(name: name, birthDate: birthDate, type: PetType.load(petTypeId), owner: Owner.load(ownerId))
    pet.save()
    pet
}

which is being used from the controller like so:

def pet = petclinicService.createPet(params.pet?.name, params.pet?.birthDate,
    (params.pet?.type?.id ?: 0) as Long, (params.pet?.owner?.id ?: 0) as Long)

I'm curious to know whether this is the best way to save something in grails? With this approach if I add another field to the Pet domain, say String color, then I'll have to touch three classes (Pet, PetController, and PetclinicService) for the change to be complete.

Is there a way I can send the entire params object into the service and have it automatically map to the domain?

like image 231
birdy Avatar asked Feb 25 '13 18:02

birdy


1 Answers

I made that change because the standard is to pass in the params map, but this is bad for a few reasons. One is that it couples the service tier to the web tier. This isn't a strict coupling since it is just a Map, but services should be reusable and independent. The other is that the map is a "magic" map where you need to know the keys in order to use it. By using named and typed method arguments, the code is more readable and understandable.

This does add a maintenance burden since as you point out adding a new field requires changing the signature, but ideally this method will be the one place where this work is done, so you only need to change it in one place.

Feel free to use params in your own code, but since this project is one of our demo projects I wanted it to use best practices where possible.

like image 194
Burt Beckwith Avatar answered Sep 29 '22 02:09

Burt Beckwith