I\'m creating a grails service that will interact with a 3rd party REST API via a Java library. The Java library requires credentials for the REST API by means of a url, use
For contexts where you can't inject the grailsApplication bean (service is not one of those, as described by Jon Cram), for example a helper class located in src/groovy, you can access it using the Holders class:
def MyController {
def myAction() {
render grailsApplication == grails.util.Holders.grailsApplication
}
}
Even though grailsApplication
can be injected in services, I think services should not have to deal with configuration because it's harder to test and breaks the Single Responsibility principle. Spring, on the other side, can handle configuration and instantiation in a more robust way. Grails have a dedicated section in its docs.
To make your example work using Spring, you should register your service as a bean in resources.groovy
// Resources.groovy
import com.example.ExampleApiClient
beans {
// Defines your bean, with constructor params
exampleApiClient ExampleApiClient, 'baseUrl', 'username', 'password'
}
Then you will be able to inject the dependency into your service
class ExampleService {
def exampleApiClient
def relevantMethod(){
exampleApiClient.action()
}
}
In addition, in your Config.groovy
file, you can override any bean property using the Grails convention over configuration syntax: beans.<beanName>.<property>
:
// Config.groovy
...
beans.exampleApiClient.baseUrl = 'http://example.org'
Both Config.groovy
and resources.groovy
supports different environment configuration.
The grailsApplication
object is available within services, allowing this:
package example
import com.example.ExampleApiClient;
class ExampleService {
def grailsApplication
def relevantMethod() {
def client = new ExampleApiClient(
grailsApplication.config.apiCredentials.baseUrl
grailsApplication.config.apiCredentials.username,
grailsApplication.config.apiCredentials.password
)
return client.action();
}
}