extract params for multiple 'routes' in a handler

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

extract params for multiple 'routes' in a handler

durbinjo593
Hey everyone-

I'm trying to figure out how to extract some optional params for multiple, but not all, routes or handlers within an action chain. (I'm probably improperly using those terms.)

See: https://github.com/joshdurbin/rx-mongo-ratpack/blob/master/src/main/groovy/io/joshdurbin/action/PeopleHandler.groovy

What I'm looking for is something more like the following where I extract the query parameters only for three of the four handlers defined in the chain.

  @Override
  void execute(Chain chain) throws Exception {

    Groovy.chain(chain) {

      all {

        Integer page = request.queryParams.page as Integer ?: 1
        Integer pageSize = request.queryParams.pageSize as Integer ?: persistenceServiceConfig.maxResultSizePerPage
        Integer evaluatedPageSize = pageSize <= persistenceServiceConfig.maxResultSizePerPage ? pageSize : persistenceServiceConfig.maxResultSizePerPage

        get("near/:lat/:long") {

          Double latitude = pathTokens.lat as Double
          Double longitude = pathTokens.long as Double

          persistenceService.getPeopleNearPoint(latitude, longitude, page, evaluatedPageSize).toList().subscribe() { List<Person> people ->

            render json(people)
          }
        }

        get("in/:postalCode") {

          String postalCode = pathTokens.postalCode

          persistenceService.getPeopleInPostalCode(postalCode, page, evaluatedPageSize).toList().subscribe() { List<Person> people ->

            render json(people)
          }

        }

        get {

          persistenceService.getPeople(page, evaluatedPageSize).toList().subscribe() { List<Person> people ->
            render json(people)
          }
        }
      }

      post {
        def form = parse(Form)

        persistenceService
          .insertPerson(form)
          .subscribe { Person person ->
            redirect "/person/${person.id}"
        }
      }
    }
  }
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

danveloper
Administrator
You can use the context registry for managing this kind of inter-handler communication.

import static ratpack.groovy.Groovy.ratpack

class PageModel {
        Integer page
        Integer pageSize
        Integer evaluatedPageSize
}

ratpack {
       
        bindings {
                module(JacksonModule)
                bind(PersistenceService, DefaultPersistenceService)
        }

        handlers {
                all { PersistenceService persistenceService ->
                        Integer page = request.queryParams.page as Integer ?: 1
                        Integer pageSize = request.queryParams.pageSize as Integer ?: persistenceServiceConfig.maxResultSizePerPage
                        Integer evaluatedPageSize = pageSize <= persistenceServiceConfig.maxResultSizePerPage ? pageSize : persistenceServiceConfig.maxResultSizePerPage
                        context.next(new PageModel(page: page, pageSize: pageSize, evaluatedPageSize: evaluatedPageSize))
                }

                all { PersistenceService persistenceService ->
                        byMethod {
                                get { PageModel pageModel ->
                                        persistenceService.getPeople(pageModel.page, pageModel.evaluatedPageSize).toList().subscribe() { List<Person> people ->
                                render json(people)
                                }
                                }
                                post {
                                        def form = parse(Form)
                                persistenceService
                                  .insertPerson(form)
                                  .subscribe { Person person ->
                                    redirect "/person/${person.id}"
                                  }
                                }

                        }
                }

        get("in/:postalCode") { PersistenceService persistenceService, PageModel pageModel ->
          String postalCode = pathTokens.postalCode
          persistenceService.getPeopleInPostalCode(postalCode, pageModel.page, pageModel.evaluatedPageSize).toList().subscribe() { List<Person> people ->
            render json(people)
          }
        }

        }
}
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

danveloper
Administrator
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

durbinjo593
Sweet. That makes sense, but the API doesn't seem to support that syntax -- adding a random object via context.next(...).

I changed it to context.next(single()), which compiles and runs, but I get a NPE when I try to inject the PageModel into the downstream handlers.

See: https://github.com/joshdurbin/rx-mongo-ratpack/blob/master/src/main/groovy/io/joshdurbin/action/PeopleHandler.groovy

Also, Dan (or others), can you take a second a look at Jackson in this project. I upgraded last night to yesterday's release and ripped out the jackson module and have tried combinations of the Init in core, etc... etc... with no luck. Essentially I'm getting an exception that there isn't a supported renderer.
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

danveloper
Administrator
Ah yes -- my fault :-)
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

danveloper
Administrator
In reply to this post by durbinjo593
You need:

module JacksonModule

in your `bindings` block, here: https://github.com/joshdurbin/rx-mongo-ratpack/blob/master/src/ratpack/Ratpack.groovy#L23
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

durbinjo593
Ahhh. Re: Ratpack, the module changed. Got it.

--

Any thoughts on the NPE with the addition of the PageModel to the registry? I still feel like I'm doing something wrong.

Request to /people yields:

java.lang.NullPointerException: Cannot get property 'page' on null object
        at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:57)
        at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:169)
        at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:293)
        at io.joshdurbin.action.PeopleHandler$_execute_closure1$_closure3$_closure6$_closure7.doCall(PeopleHandler.groovy:52)
Reply | Threaded
Open this post in threaded view
|

Re: extract params for multiple 'routes' in a handler

Luke Daley
Administrator
It's a “bug” of sorts.

The closures used inside `byMethod()` don't support registry extraction. You'd have to move the param up to the handler level. This is something we could potentially make work.

The fact that you are getting a null, and not a runtime (or compile time if using @CompileStatic) error when coercing a Closure to ratpack.func.Block is surprising though.

What version of Ratpack are you using?