views:

90

answers:

2

In a Service of a Grails project, I like to find, at run time, the arguments of Dynamic Methods in order to inform callers.

Also, I like to call the method and if doesn't exist to return an error,

I will appeciate any help.

A: 

Not sure I understand your question, but the last part about checking if you can call a method on an object, this can be done by checking the meta class of the object you are dealing with like this.

obj.metaClass.respondsTo(obj, 'theMethodYouWantToCall')

obj is the object you want to call the method on, and theMethodYouWantToCall is the name of the method you want to call. respondsTo will return an empty list [] if the method you are trying to call is not found

omarello
Thans for your prompt answer.That I like to do is to set-up a Rest layer which will receive requests that will correspond to Dynamic Methods like ../Account/findAllWhere?...I do not like to build corresponding services but the controller will handle it dynamically.
nick
+1  A: 

You can configure URLMappings in grails to get the value of the dynamic method and call it against your object for example you can do the following

  • In your urlMappings.groovy define a mapping with two embedded variables object and method

    "/$object/$method" (controller:"api",action:"invoke")

  • Define a 'api' controller with an invoke action. See code below with the logic on how to invoke the method on the object

    import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
    class ApiController {
        def invoke = {
            def object = params.object
            def method = params.method
            def args
            if(object) {
                def domainClass = AH.application.domainClasses.find{it.name == method}?.clazz
                if(domainClass.metaClass.getStaticMetaMethod(method,args)) {
                    domainClass.metaClass.invokeStaticMethod(target,input.method,args)  
                }
            }
        }
    }
    

In my example, I assumed that you're calling a static dynamic finder on the domain class. You can generalize this to handle instance methods as well. You need however to provide more information such as the object id, in your request to load the object and call the method against it.

"/$object/$id/$method" (controller:"api",action:"invoke")

-Ken

ken
Even if this doesn't answer the question, i really like the idea. One Up.
omarello
Based my answer more on his comments on your answer :)
ken