user3884200
user3884200

Reputation:

Can we validate in Service of Grails

static constraints = {}

In documentation they said that it work in Domains . Can we apply constraints in services if we create variables in it ?

Upvotes: 0

Views: 274

Answers (4)

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27220

Can we apply constraints in services if we create variables in it ?

Yes. A long time ago we introduced the @Validateable annotation which allows you to make just about any class which is written in Groovy, including Service classes, validateable. See the project at https://github.com/jeffbrown/validateableservice which includes the following:

grails-app/services/demo/PeculiarService.groovy

package demo

@grails.validation.Validateable
class PeculiarService {

    String someString

    static constraints = {
        someString matches: /[A-Z].*/
    }
}

test/unit/demo/PeculiarServiceSpec.groovy

package demo

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(PeculiarService)
class PeculiarServiceSpec extends Specification {

    void "test validation"() {
        when: 'someString begins with a lower case letter'
        service.someString = 'invalid'

        then: 'validation fails'
        !service.validate()

        when: 'someString begins with an upper case letter'
        service.someString = 'Valid'

        then: 'validation passes'
        service.validate()
    }
}

Note that if your service has state like this you almost certainly don't want the service to be a singleton, which is the default scope. Also, there is almost certainly no good reason to ever make a service validateable but the answer to the question as asked is "yes".

Upvotes: 1

Grzegorz Gajos
Grzegorz Gajos

Reputation: 2363

You shouldn't validate service. Better look at command objects or @Validatable annotation.

Upvotes: 0

Burt Beckwith
Burt Beckwith

Reputation: 75671

You can't do what you're asking, i.e. drop a constraints block into a service and expect it to be recognized and used. For one, which domain class(es) would that block pertain to? A service isn't tied in any way to an individual domain class, so it would be more involved than just creating a block.

You can externalize validation however. Grails uses Spring MVC under the hood, and the validation support from that. It's not obvious that this is happening, but if you look at all of the beans in the ApplicationContext you'll see that each domain class has an associated validator bean that implements Spring's Validator interface, and it uses the rules defined in constraints blocks to do validation. You can do something similar by implementing that interface and doing whatever checks you like. It would be tricky to parse a constraints block because it has a custom DSL, so you'd need to see how Grails parses it and do the same thing.

I wrote about this in my book if you want to see more details. I would copy/paste that here - I'm not trying to generate sales - but it's somewhat far fetched and you're really better off using the standard approach. I only figured out how to do what I described for fun and thought it'd be interesting to add to the book to illustrate one of the many ways Grails uses Spring.

Upvotes: 1

Vitor Hugo
Vitor Hugo

Reputation: 1126

From the grails docs (http://grails.org/doc/2.3.4/guide/single.html#validation):

Most commonly they are applied to domain classes, however URL Mappings and Command Objects also support constraints.

So the answer is no.

Upvotes: 0

Related Questions