Modules vs. Global services

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Modules vs. Global services

tomaslin
Is there a way to make modules apply to every handler of a particular script?

I'm looking at examples like this one - https://github.com/danveloper/ratpack-mongo/blob/master/src/ratpack/ratpack.groovy 

And it seems pretty odd to include the { PeopleDAO dao -> } into every handler.

The alternative seems to be adding a global service to the ratpack file, but it feels slightly hacky and I wondered if there are any best practices suggested for this.
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

Luke Daley
Administrator
Modules do apply to all handlers, in that their contents are available in all handlers… but I suspect that's not what you're asking.

> And it seems pretty odd to include the { PeopleDAO dao -> } into every handler.

I don't think that this is odd. Handlers need to get access to the things that they use somehow. Making things implicitly available is a recipe for disaster and makes things difficult to test.

There's no real alternative without resorting to dynamic programming, and that's strictly not allowed in Ratpack core.

> The alternative seems to be adding a global service to the ratpack file, but it feels slightly hacky and I wondered if there are any best practices suggested for this.

I'd rather it be explicitly global in the script than magically implicitly available.

What's missing is some kind of hook to retrieve something from the Guice context after it's been created so you can keep a script local reference. There's no real way to do this right now. I'll think on it.


BTW, there's an alternative to declaring dependencies via closure params…

<code>
get("somePath") {
  get(PersonDAO).someMethodOnPersonDaoInstance()
}
</code>

The second get there means “get the service of this type”.
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

Luke Daley
Administrator
I have an idea…

We could allow the handlers {} closure to take params…

<code>
modules {
  …
}
handlers { PersonDAO p ->
  get("foo") {
    p.stuff()
  }
  post("bar") {
    p.stuff()
  }
}
</code>

How does that strike you?
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

tomaslin
Sounds like a good solution to me.
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

tomaslin
Had a thought about this a little bit more,

Maybe what would be nice is to be able to group module dependencies at a higher level.

What would be ideal would be something like a withModule that works as follows:

<code>
modules {
  …
}
handlers {

  withModule{ PersonDAO p ->
    get("foo") {
      p.stuff()
    }
    post("bar") {
      p.stuff()
    }
  }

  withModule{ CarDAO c ->
    get("car/foo") {
      c.stuff()
    }
    post("car/bar") {
      c.stuff()
    }
  }

}
</code>

This way, you have higher level groupings but also the flexibility to define module groups
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

Luke Daley
Administrator
Hmm, not sure.

One thing, module doesn't mean what you think it does. A module has a specific meaning in Guice and therefore Ratpack: it's like a Spring Application Context. That is, it defines how objects are bound to types. So in your example, withModule() doesn't make sense as a method name. It would be withServices() or something similar.

What you propose would be very difficult to implement as it would couple ratpack-core (or at least ratpack-groovy) to Guice (which it currently isn't). I might be able to find a way around this.

I'm not convinced about the use case though. I think it might be better to do the global stuff and see in what cases that is deficient.
Reply | Threaded
Open this post in threaded view
|

Re: Modules vs. Global services

Luke Daley
Administrator
This is available in the latest snapshot.