respond grails grails-controller

respond - Inyectar la configuración de la aplicación de grails en servicio



grails respond (3)

Aunque grailsApplication se puede inyectar en los servicios, creo que los servicios no deberían tener que lidiar con la configuración porque es más difícil probar y rompe el principio de responsabilidad única . Spring, en el otro lado, puede manejar la configuración e instanciación de una manera más robusta. Grails tiene una sección dedicada en sus documentos.

Para que su ejemplo funcione con Spring, debe registrar su servicio como un bean en resources.groovy

// Resources.groovy import com.example.ExampleApiClient beans { // Defines your bean, with constructor params exampleApiClient ExampleApiClient, ''baseUrl'', ''username'', ''password'' }

Entonces podrá inyectar la dependencia en su servicio

class ExampleService { def exampleApiClient def relevantMethod(){ exampleApiClient.action() } }

Además, en su archivo Config.groovy , puede anular cualquier propiedad de bean usando la convención de Grails sobre la sintaxis de configuración: beans.<beanName>.<property> :

// Config.groovy ... beans.exampleApiClient.baseUrl = ''http://example.org''

Tanto Config.groovy como resources.groovy admiten diferentes configuraciones de entorno.

Estoy creando un servicio de Grails que interactuará con una API REST de terceros a través de una biblioteca Java. La biblioteca Java requiere credenciales para la API REST por medio de una url, nombre de usuario y contraseña.

Me gustaría almacenar estas credenciales en la configuration/Config.groovy , ponerlas a disposición de un servicio y garantizar que las credenciales estén disponibles para el servicio antes de que lo requiera.

Agradezco que grailsApplication.config esté disponible para los controladores y que a través de un método de un servicio, los valores de configuración relevantes puedan ser proporcionados al servicio, como este:

package example class ExampleController { def exampleService def index = { } def process = { exampleService.setCredentials(grailsApplication.config.apiCredentials) exampleService.relevantMethod() } }


package example import com.example.ExampleApiClient; class ExampleService { def credentials def setCredentials(credentials) { this.credentials = credentials } def relevantMethod() { def client = new ExampleApiClient( credentials.baseUrl, credentials.username, credentials.password ) return client.action(); } }

Siento que este enfoque es un poco defectuoso ya que depende de un controlador que llame a setCredentials() . Tener las credenciales disponibles para el servicio automágicamente sería más sólido.

¿Es viable alguna de estas dos opciones (actualmente no estoy lo suficientemente familiarizado con Grails)?

  1. ¿Inyectar grailsApplication.config.apiCredentials en el servicio en el controlador cuando se crea el servicio?

  2. ¿Proporciona algún tipo de contructor en el servicio que permita pasar las credenciales al servicio en el momento de creación de instancias?

Tener las credenciales inyectadas en el servicio es ideal. ¿Como se puede hacer esto?


El objeto grailsApplication está disponible dentro de los servicios, lo que permite esto:

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(); } }


Para contextos en los que no se puede inyectar el bean GrailsApplication (el servicio no es uno de ellos, como lo describe Jon Cram), por ejemplo, una clase auxiliar ubicada en src / groovy, puede acceder a ella utilizando la clase Holders :

def MyController { def myAction() { render grailsApplication == grails.util.Holders.grailsApplication } }