Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active August 25, 2022 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xliff/c7e4b55598de3904a2be6d64c541ca9a to your computer and use it in GitHub Desktop.
Save Xliff/c7e4b55598de3904a2be6d64c541ca9a to your computer and use it in GitHub Desktop.
Methods as Cro Controllers

So I was looking through what I have written for $dayJob, as far as my work with a Cro-based application server is concerned.

It occurred to me that we might be able to clean up what is already a fairly clean Cro dispatch handler.

Consider this example:

  route {
    get ->                { ... }
    get -> '2'            { ... }
    get -> 'two', 'three' { ... }
  }

Might we be able to clean that up considerably using class methods? I would imagine that with some work, this could be converted to:

  method no-args                   is controller<get> { ... }
  method one-arg  ('2')            is controller<get> { ... }
  method two-args ('two', 'three') is controller<get> { ... }

How could we construct the route block to use the above methods?

@jnthn (Cro's author) came up with this:

Probably the best way - if wanting to plug into the router - is to provide 
a role that implements Cro::Transform from HTTP request to HTTP response, 
maps requests to the correct method, and then use it as `delegate 'foo', 
ThatObject.new'. Ah, [but] delegate is probably taking a pair, so 
`delegate foo => ThatObject.new;`, [...] though if you meant that you want 
to just subscribe methods to the `get`/`post` calls, then you can do it 
using `assuming`"

Which is a great idea, but I wonder if we can automate the route block entirely.

I'd expect such a thing might look like so:

method routes {
  route {
    for self.^methods.grep( Controller ) {
      my &wrapped-method = .assuming(self);
      given .web-method {
        when 'get'    { get:    &wrapped-method }
        when 'post'   { post:   &wrapped-method }
        when 'delete' { delete: &wrapped-method }
        ...
      }
    }
  }
}

Where Controller is an identifying role that is added to each method that is used in the route block.

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment