Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Route tree would be more efficient if it started with pathPrefix(docsPath) #37

Open
nsterling opened this issue Sep 19, 2014 · 3 comments

Comments

@nsterling
Copy link

If I'm understanding correctly what's going on in the definition of routes, it produces a concatenation of routes r0 ~ r1 ~ r2 ~ r3 ~ ... ~ rN for the N resources in the API (plus one at the beginning for the entire set), each with a matcher for a docsPath segment in the URL. That concatenation is wrapped in matchers for media type JSON and method GET.

In a JSON REST API, many incoming requests will be JSON GETs; such a GET will have to pass through N + 3 matchers in order to be rejected by this route tree. If these routes are placed at the end, then this hardly matters, but if someone were to put it earlier it could be an issue.

Alternatively the route tree could first match on the docsPath, thus causing non-Swagger requests to be rejected immediately. Then pathEnd (or pathEndOrSingleSlash, to be nicer) could be used to match the case where there was nothing following, like so:

final def routes: Route =
  pathPrefix(docsPath) {
    respondWithMediaType(`application/json`) {
      get {
        pathEndOrSingleSlash {
          complete(toJsonString(api.getResourceListing()))
        } ~ (
            (for (
              (subPath, apiListing) <- api.listings)
            yield {
              path(subPath.drop(1).split('/').map(
                segmentStringToPathMatcher(_))
                  .reduceLeft(_ / _)) {
                    complete(toJsonString(apiListing))
                  }
           }).reduceLeft(_ ~ _))
      }
    }
  }
@mhamrah
Copy link
Contributor

mhamrah commented Sep 20, 2014

Interesting; this would be a good iteration on the route structure. I'll
try and add, but please, feel free to submit a pull request.

Thanks,

Mike

On Fri, Sep 19, 2014 at 2:52 AM, nsterling [email protected] wrote:

If I'm understanding correctly what's going on in the definition of
routes, it produces a concatenation of routes r0 ~ r1 ~ r2 ~ r3 ~ ... ~ rN
for the N resources in the API (plus one at the beginning for the entire
set), each with a matcher for a docsPath segment in the URL. That
concatenation is wrapped in matchers for media type JSON and method GET.

In a JSON REST API, many incoming requests will be JSON GETs; such a GET
will have to pass through N + 3 matchers in order to be rejected by this
route tree. If these routes are placed at the end, then this hardly
matters, but if someone were to put it earlier it could be an issue.

Alternatively the route tree could first match on the docsPath, thus
causing non-Swagger requests to be rejected immediately. Then pathEnd (or
pathEndOrSingleSlash, to be nicer) could be used to match the case where
there was nothing following, like so:

final def routes: Route =
pathPrefix(docsPath) {
respondWithMediaType(application/json) {
get {
pathEndOrSingleSlash {
complete(toJsonString(api.getResourceListing()))
} ~ (
(for (
(subPath, apiListing) <- api.listings)
yield {
path(subPath.drop(1).split('/').map(
segmentStringToPathMatcher())
.reduceLeft(
/ )) {
complete(toJsonString(apiListing))
}
}).reduceLeft(
~ _))
}
}
}


Reply to this email directly or view it on GitHub
#37.

@nsterling
Copy link
Author

I will try to do so in the next week or so.

@fabiofumarola
Copy link

I agree, it would be an interesting feature, anyway I found useful doing

  val pathPrefix = "api" / "feed"


  def addRoute = post { path( pathPrefix / "add")
    entity(as[FeedSource]) { feed =>
      complete(addFeed(feed))
    }
  }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants