← Basic Concepts Circumflex Web Framework Documentation

Advanced Concepts

This topic reveals some nitty-gritty details about Circumflex Web Framework internals.

Matching

The central abstractions of the route matching mechanism are:

Match objects are designed to be used inside attached blocks of routes, where you can naturally assume that match succeeded:

get("/:name") = uri("name")

Match also has name which reflects the context where match has occured. URI-based matcher returns Match with name uri while headers-based matchers create Match objects with the name of corresponding HTTP header.

You can lookup certain Match object in CircumflexContext by it's name:

get("/foo" & Accept("text/:format")) = ctx("Accept") match {
  case m: Match => "Requested format is " + m("format")
  case _ => ""
}

In general you don't have to lookup Match objects, the param helper can retrieve named parameters from all matches that appear in CircumflexContext. So the previous example could be rewritten in much more convenient manner:

get("/foo" & Accept("text/:format")) = "Requested format is " + param("format")

However, there are situations where looking up a Matcher can come in handy. For example, you cannot access splats (wildcard matches) or indexed parameters with param:

get("/foo" & Accept("text/+")) = ctx("Accept") match {
  case m: Match => "Requested format is " + m(1)
  case _ => ""
}

Standard RegexMatcher can also accept an arbitrary regular expression, the groups will be accessible from Match by their index:

get("/posts/(\\d+)".r) = {
  val id = uri(1).toLong
  // lookup the post by id and render response
  "..."
}

Router Prefix

You may optionally specify the prefix for request router. All URI-based matchers inside the router will be prepended by this prefix:

class PostsRouter extends RequestRouter("/posts") {
  get("/") = "Showing posts"                  // matches GET /posts/
  get("/show/:id") = "Post " + param("id")    // matches GET /posts/show/149
}

Alternatively, you can let the enclosing router specify a prefix for subrouter:

class SubRouter(prefix: String) extends RequestRouter(prefix)

class MainRouter extends RequestRouter {
  new SubRouter("/prefix-a")
  new SubRouter("/prefix-b")
}

Note that main request routers should have the default zero-arguments constructor, so the prefix must be hardcoded. Generally, main routers have "" prefix (unless different filter mappings are specified in web.xml).

← Basic Concepts Circumflex Web Framework Documentation