Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
66 lines (45 sloc) 2.48 KB

Plans and Intents

Unfiltered conditionally handles incoming requests using partial functions. From the application's perspective, requests are mapped to code paths by pattern matching. The library uses a particular vocabulary to refer to the agents of this process without ambiguity.

  • An intent is a partial function for matching requests.
  • A plan binds an intent to a particular server interface.

For example, the @extrefunfiltered.filter.Plan trait extends the javax.servlet.Filter interface. It declares an abstract intent method for clients to define the intent partial function.

Making Plans of Intents

Looking back at the example on the previous page, you might wonder where the plan ends and the intent begins.

@@snip { #example1 }

In this case a plan is constructed directly from an anonymous partial function—that function is the intent. We can define the same plan in more explicit parts, as is usually necessary in a larger application.

@@snip { #example2 }

Since this kind of plan is an implementation of the servlet filter interface, we can pass it directly to a servlet container.

@@snip { #example3 }

Passing on That

Since an intent is a partial function, it may be undefined for a request. In this case the request may be handled by some other intent or it could produce a 404 error from the server.

Unfiltered also supports an explicit mechanism to specify that a matched request should not be handled by an intent: the Pass object.

@@snip { #example4 }

This intent avoids handling anything under /admin by matching that condition and passing on it. There are other ways to achieve the same ends, but an explicit Pass is often the most straightforward.

Keep in mind that Scala's partial functions are unaware of Unfiltered's Pass mechanism, so the intent above is in fact defined for the excluded paths. But when attached to a plan, requests that evaluate to Pass are treated the same as those that are undefined.

Chaining Intents

When you want to combine intents within a single plan, use onPass:

@@snip { #example5 }

The onPass method is defined implicitly for PartialFunction with the import of the unfiltered.response._ package. It works like orElse but is aware of the Pass object and it's optimized to avoid unnecessary reevaluation of pattern guards.