futility of extensions and matching (+ solution)

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

futility of extensions and matching (+ solution)

chris_lewis
Hey all,

I've had pain with mapping extensions to matchers before, and I've been banging my head on this one problem. Having arrived at a solution, I wanted to get some feedback. Consider the simple pattern for a Json/Jsonp endpoint:

case GET(Path("/hello", Jsonp.Optional(jsonp, _))) ....

Using jQuery and XHR, I can trigger this as long as I force the content type to an accepted type. However, if I need to trigger it via cross-domain Jsonp (and I do), I'm just plain screwed at the moment. Cross-domain calls are not XHR but dynamic script nodes, so content type tweaking is out. Path("/hello") matches exactly "/hello" so file extensions are out.

Not wanting to write two matchers for essentially the same pattern, I introduced a new extractor:

object Base {
  def unapply(s: String) =
    if(s contains '.')
      Some(s take(s lastIndexOf '.'))
    else
      Some(s)
}

With this additional extractor, this matcher works as expected:

case GET(Path(Base("/hello"), Jsonp.Optional(jsonp, _))) ...

The Json(p) matcher now gets a chance to evaluate the extension if no appropriate headers are present, instead of being the victim of a strict string comparison. I haven't committed this to my fork, but I will certainly be using it going forward, unless of course there is a better solution.

thanks,
chris
Reply | Threaded
Open this post in threaded view
|

Re: futility of extensions and matching (+ solution)

soft_props
That's a great point Chris. I was kicking around some ideas on having more extractors for url checking and extraction. I ran into an issue in some oauth work when trying to get a ref to the full url of the request and ended up just using the underlying httpServletRequest. I'll have some time this weekend to work on it.

In your case though you can use a built in extractor, regex's

Below is an example of how you might serve both

https://gist.github.com/743169

Basically you can extract what ever format you want from a string with a regex in scala.

Nathan used to have some nice examples using a combination of Path, Seg, and regex's to do typesafe format checking extractors.

We are prob overdue for more of that kind of documentation. We've been trying to pull executable documentation examples into g8 templates. I've gotten enough questions about the json module that I should probably put together a g8 template for javascript based apis. I'll look into that this weekend.

Hope that helps :)
Reply | Threaded
Open this post in threaded view
|

Re: futility of extensions and matching (+ solution)

chris_lewis
Cool. For what it's worth I almost always want the behavior where the extension indicates the response type - it'd be handy to have baked in.

Thanks again!