The Bowler Manual

This is the Bowler manual and will continually be expanded on. In addition to this manual, the Bowler Example Application and the Bowler Quickstart are good places to start getting into Bowler and how it works.

Deeper Customization

  • Multi-Channel Support
    • View Suffixes for Client/Request Specific Views
  • Customizing the Framework
    • Request Mapping Strategies
    • Render Strategies & View Renderers

SBT or Maven dependencies

Bowler Core

Simple Build Tool
The below Simple Build Tool (sbt) project file should give you all you need to start using Bowler if you're a Sbt user (place the file in your project/build folder). It should download all the dependencies required from Sonatypes public repo once you run the sbt "update" command. Bowler is currently built against Scala 2.8.1 and Scala 2.9.0: Sbt uses Ivy under the covers for dependency management, unfortunately Ivy is not great at resolving transient dependencies that are more than one level deep, therefore the extra repository location definitions are necessary for sbt.
Getting Started Using Maven
If you're using Maven, you need to add the following into your pom.xml (in addition to the other Scala stuff you may want to set up for compilation):

Bowler with Squeryl Integration

If you want Squeryl integration you may want to add the following lines to the project description shown in the previous section (last two are optional, and you should add a dependency on the JDBC driver for your deployment database): Also, compared to the baseline Bowler project, you can remove the dependency on "bowler-core", as this is implicit through "squeryl-mapper". For Maven users, I'm sure you can deduce the dependency definitions from the example here and in the previous section.

Bowler with JPA Integration

Below are the extra settings required for JPA integration compared to the base build, the comments explain the specific reasons for some of the dependencies: For Maven users, again, hopefully you can deduce what the dependencies and repo definitions are, as they follow the Maven format, but are defined in sbt's style.

SNAPSHOT releases

The Bowler project will occassionally, but unfrequently make snapshot releases for the framework when major milestones are reached in development or bug fixes are made, but there is not sufficient QA done to make a full release. These will reside in the Sonatype SNAPSHOTS repository.
The current SNAPSHOT release is 0.5-SNAPSHOT

Application Setup

Below is an example of the web.xml for a typical Bowler application: The only thing of note here is the BowlerFilter (you could also use BowlerServlet), which takes an init-parameter called "bootstrapClass". The bootstrapClass is simply the starting point of your application, where as the name implies, you bootstrap your whole application.
Below is an example of a minimal Bowler bootstrap class: The Bootstrap class above is a simple basic class with a no-args constructor, which does the following from top to bottom:
  • Sets up a default view Layout for the application
  • Starts a Controller that responds to Requests
  • Sets the Scalate RenderEngine to disallow caching and allow reloading - this will slow down rendering, but is useful if you want to change Scalates on the fly during runtime during development
That's it, there's really not much more to setting up a basic Bowler Applications! Of course, you could add much more here: more Controllers, add StringValueTransformers to the TransformerRegistry for looking up complex objects based on request parameters such as id's, add more complex Layouts etc.

Application Structure

A typical Bowler Application, as seen from a Maven or SBT default project structure will have a structure as follows:
  • src/main/
    • webapp/WEB-INF/web.xml
    • scala/[yourpackage] (your application sources)
    • scala/[your validator package] (package with your validator classes)
    • resources/layouts/ (location for your application layouts)
      • default.mustache (illustration of possible default layout location)
    • resources/views/ (location for your views)
      • GET/ (views are held in locations based HTTP Method and path, for instance "GET /" could be in "/views/GET/index.mustache")
        • index.mustache (illustration of possible template name. Can be .mustache, .ssp, .jade or .scaml)
    • resources/[your validator package] (package with your validator .properties message files)
What is noteworthy above is that views and layouts are kept on the classpath, layouts on the /layouts/ path, and views in the /views/ package, followed by the HTTP Method and path, for instance /views/GET/somepath.ssp.

The Controller - Defining Routes/URL's

You define "routes" in Bowler based on the approach inherited from Scalatra, which Bowler is built on top of. You typically do this by inheriting the Controller trait and adding your Controller in the bootstrap-class of your application.
Below is an example of a simple Controller, please note the comments: In the example above, you can see that each HTTP Method has it's own equivalent verb in the Bowler DSL which allows you to create an application route that takes a Request and Response as arguments.
We can also do wild-card URL's as follows: ..this will make the wildcards available in a special case request variable called "splat" in the form of a List in the order of the wildcards.
But that's not all, we can also have regular expression routes: In a similar manner to the wildcards, the regex values captures will be available in a special case request variable called "captures" in the form of a List in the order of the wildcards.
It should be noted that regex and wildcard URL's view mappings need to be explicitly made, as the file system of some operating systems, notably Windows do not support some of the strange characters that may otherwise ensue. More about this in the section Template Mapping.

Ordering of Routes

It is important to note that your routes could clash if you define them carefully, in this case the last defined route takes precedence. For instance if you have the route "/resource/:id" defined, and then "/resource/new", any requests to /resource/new will go to the equivalent request handling closure but every other request that matches "/resource/:id" will go to that request handling closure. Even though "/resource/new" matches the "/resource/:id", it will take precedence IF it was defined later in the class. If it was defined before "/resource/:id", it will never be called!

Concise Routes by Function Name Convention

If you want to use a more concise style of creating routes, you can do so by extending the org.bowlerframework.controller.FunctionNameConventionRoutes-trait in your Controller: As you can see in the example above, this gives you the power of creating routes "auto-magically" by function name convention with support for regular URL's, named parameters and wildcards just as in the routes defined in the previous section, all you have to do is use the convention of GET|PUT|POST|DELETE followed by a space and your ROUTE as a function name, and it will automatically be added as a route. To do this, you will need to enclose your function name in back-ticks.
Another added benefit of using the function-name convention for routes is that Requests will be automatically mapped to your type-safe objects in your function-parameter signature, with name-hints being used as the name of your parameters.
Also, if your Controller does not extend "Renderable", the controller will assume that you will want to render the return result of your function as it's view-model. To override this default behavior, simply make your Controller implement Renderable.
The obvious trade-off that function name convention mapping of routes does is that it trades convenience and conciseness for a minor loss of type-safety, though this should be quite easily tested using the ScalatraFunSuite testing trait.

The View

Bowler uses Scalate for it's View and Layout templating. Bowler supports all of Scalate’s templating styles, including Mustache, SSP, Scaml, Jade and Scuery.
For more detailed documentation on how to use the templating languages themselves, please refer to the links above that lead to Scalate's manual pages. However, a quick primer of the choices:
  • SSP is sort of like JSP for Scala, but much, much nicer without a lot of the problems that come with JSP.
  • Scaml is like Ruby's Haml, but for Scala, a very DRY style of generating markup
  • Jade similar to Scaml, by even DRY:er
  • Mustache Scala dialect of Mustache, logic-less templates that also work in a Browser with Mustache.js
  • Scuery is slightly different from the others in that it is quite similar to Apache Wicket's templating style, separating XML-markup from manipulating Source. Uses CSS-selectors to manipulate a template. Very useful for writing Component-oriented UI's and re-usable Components
Bowler of course allows you to mix-and-match the above templating styles transparently within an Application, so for instance using Jade as your view, and including Squery based Components is entirely possible.

The Resource View - Separating View Model from Layout

The default Bowler setup makes a distinction between the Resource View and the Layout. The rationale behind this is simple: in a truly RESTful application, by getting a resource at a URL you are primarily interested in the details of the resource (most commonly a model object or several models in our case), not the "decoration" around it - navbars, headers, footers and other things you may get with a desktop browser are there for usability, but often have very little to do with the resource itself. This is why we make this distinction, more about the rationale behind can be found in this blog post.
Given this background, a rendered View in Bowler will usually consist of a Resource View and a Layout that wraps around the Resource View.

Consider the following case class and controller: Now, consider the above controller with the following view at the classpath location of /views/GET/showAWidget/index.mustache This should render the following (excluding any layout around it for simplicity of the example): There are a couple of things to learn from this: by extending our controller with Renderable, we get access to the render function, which is a vararg function that will invoke the rendering with your model objects. Render will eventually map your model into an appropriate model for Scalate and the mustache template to render in this case. We'll deal with this in a second.
The render function is central here: as you can see, you only pass in your model, or any arbitrary model objects that represent your resource, but you don't actually give it any information on how to render the model. This is important, especially if you want to render to multiple outputs, for instance JSON (which you get for free, more on that later) and HTML.
What about Dropdowns and other UI elements that need additional models?
Dropdowns and other elements may require additional backing model data which isn't part of your immediate Resource, for instance a Resource Model may have another Resource set on it in a relationship, but you may have a form where you want to choose from a number of possible options in a dropdown.
In this case the Mustache template format is probably unsuitable in this particular case. The best practice in this case is to use something like an SSP template and a re-usable Bowler UI Component - this is detailed in the section Re-usable UI Components.

Scalate Templates & View Model Aliases

As we could see in the above example, the Widget case class instance somehow got mapped into a Scalate model object called "widget" for the benefit of the template, how did this happen and what governs this? It's really quite simple, there are a couple of simple rules around this:
  • By default, a class passed as View Model will be called it's lower case equivalent, for instance com.mypackage.Widget will become widget in the template.
  • Sets, Seqs, Lists and java.util.Collection's will be called the plural form of the objects contained, for instance a List[Widget] would become widgets. In this sense, the pluralisation is a bit dumb and only appends an "s" to the type alias
  • You can override this behavior by wrapping whatever View Model you pass in in a ViewModel object giving it the new alias as a constructor argument.
  • Finally, you can override the default alias by registering another one in the AliasRegistry
Given these basics, other template specific questions are probably best answered by the Scalate documentation, and depending on your preference of Scalate supported templating language, more specifically the Mustache, SSP, Jade or Scaml docs.
Personally, I have a preference for Mustache templates in most cases, as they are logic-less and avoid any temptation to include backend application logic in the template and all the potential stupid things that can come with that.

Template Mapping & Paths

As we have mentioned, we support all Scalate template types out of the box. The resolution of whether it is a .mustache, .jade, .ssp or .scaml template is done "auto-magically", so you may happily mix various types if you need/want to.
As we also mentioned, views are typically in a path according to the following format (assuming you use the default locations): /views/[HTTPMETHOD]/[firstpartofpath]/[secondpart].[mustache|ssp|jade|scaml] There are some notable special cases around this (we'll use .mustache files here for simplicity, though you could use any scalate supported type):
  • The root of a folder/path should have an index.mustache file.
  • For named variables, like ":id", the semi-colon is replaced by an underscore, so request to GET "/widgets/:id" would be mapped to for instance a mustache template at /views/GET/widgets/_id.mustache. This also goes for multiple levels of nested named parameters: folders can also be prefixed with the underscore
  • Regex and Wildcard URL's need to have their view templates set explicitly by calling Renderable.renderWith with a ViewPath or Scuery Component to explicitly tell what view to use. You can do renderWith for any other regular route as well, should you want to re-use the view for another route, so you do not need to duplicate markup for route's that share views.
  • Any other route can also have their related view overriden as above, this can be useful if you want to re-use the same view across several routes.
Localisation
Localisation of Views and Layouts in Bowler is easy - simply copy your original template and suffix the filename before the file-ending with the locale: For instance, a file called index_se.mustache will take precedence over index.mustache if the users browser has a Swedish locale set.

Re-usable UI Components & Scuery

The Scalate SSP template format (as does Jade and Scaml) allows you to call Scala code from your template. Adding lots of code/logic in your template is generally not a good thing, however if you do it cleanly as in the example below, you are using a style which is clean, concise and nice with a minimum of actual code: What happens in the template snippet above is that we have imported the functions & values of "SimpleComponent" to be available in the template, we then call the "show" function on the SimpleComponent singleton object with a Tuple2 parameter, for which the resulting string is unescaped by Scalate so that any resulting HTML is returned without being escaped (be careful if you are returning user input data and filter it for scripts!).
What is key to creating re-usable components in this manner is:
  • Create a singleton object and import it as in the example above.
  • Call a function as above that will return a String with the contents that you want to display in place of the code
  • If using SSP, you may pass any type-safe parameter you wish to the function as an argument
By doing this, you are effectively creating the equivalent of a Wicket Component, Lift Snippet or JSP custom tag, if you are familiar with any of these technologies.
Enter Scuery
A useful way of creating re-usable components in this manner is to rely on Scalate Scuery Components, as allowed by Bowler.
Scuery Components in Bowler require two things: a markup file that is valid XML/XHTML (with open and close start tags) on the classpath in the same package as your Component class: And a related Component class to accompany the markup: Components can have other Components and be composed in any way you wish, including using markup inheritance: if a Component does not have it's own markup, it will check if it's parent Component has the markup instead.
Further, localisation for Scuery Components follows the same name-suffix rules as other Bowler templates.
As you can see from the example above Bowler Scuery Components use CSS-selectors to select what XML/HTML elements that the code will manipulate.
To use Scuery Components as View's you have two options:

Return JSON or HTML?

Given the separation of Resource View and Layout that we have been banging on about, rendering JSON instead of HTML is really simple: if you set the HTTP "accept" header on a request to "application/json" the server will render a JSON representation of your View Model. Consider the following JQuery code: That's really all you need to emit JSON back to the client! Imagine how simple it becomes to create rich, interactive, JavaScript heavy webapps when you don't have to duplicate work to return JSON instead of HTML! For instance, if you did a GET request to a route that rendered the Widget we used previously, it might emit something like this: It should be noted that JSON rendering only works well for Scala case classes

Layouts

Basics
If we consider the simplest case which we showed in the Application Setup section, setting up a layout is as simple as it is shown in the Application Setup section. But to re-cap, here are the lines again: For a relatively simple layout, this is all you need. The reason we set a function to resolve a Layout is so that in case you have more complex layouts, or you want to use a different layout dependent on Request characteristics (such as which host-name a request is coming to), you can create a more complex function if you want.

If you create a default layout with name "default", using mustache, it will be in the classpath location of /layouts/default.mustache. So we may have the following layout: The {{&doLayout}} is the place where your Resource View will go when rendered. Also "doLayout" is the default name given to the place for the Resource View, unless you specify a custom LayoutModel, in which case it becomes the LayoutModel implementors responsibility to add the resource view to the template.
There are two types of Layouts: DefaultLayout for standard Scalate templating styles (Mustache, SSP, Jade or Scaml), and ScueryLayout, for Scuery Component-based layouts.
Layout Models
A Layout may not just be as simple as some static HTML, you may want to define your own LayoutModels that look up some data that you want for your layout, for instance related articles if your resource view is displaying an article of some sort.
To do this, simply implement the LayoutModel trait, which takes the Request, View Model as a Map (in case you want to introspect this) and the rendered Resource View as a String (so you can place it in the Layout). From this, you should produce a Map that holds all the values that you want to use as models for the Layout Scalate Template.
LayoutModels are slightly closer to Scalate in terms of how the Model is given, but this is because we no longer have to strictly adhere to the Resource View/Layout split, as we are only dealing with the Layout concern.
Nested Layouts
You can also have levels of Layouts nested, for instance, you might want to have an "articleLayout" with links to related articles to wrap around an article resource view, which in turn is wrapped by a "section" layout and finally by the generic layout.
Consider the following code that should go into the application bootstrap class to see how you may wrap layers of layouts: As you can see, the composableLayout has a parent layout of "parentLayout". The Bowler framework will take care of any traversal upwards to render your whole hierarchy of layouts.
Scoped Layouts (global -> controller -> route -> view)
You can set Layouts in four different scopes, which will override the scope above it, for instance, controller scope overrides the global scope where it is used.
The hierarchy works as follows:
  • Global: set in the application Bootstrap as shown above.
  • Controller: have the Controller implement LayoutAware and set a Layout with the layout-function of LayoutAware anywhere in the Controller body.
  • Route: have the Controller implement LayoutAware and set a Layout with the layout-function of LayoutAware inside a route-definition/handling function.
  • View: import the Layout-singleton object inside your template and set a layout with Layout.layout.

The Model: POST, PUT, GET, DELETE - Handling Requests

Parameter Mapping: Mapping Requests to Beans/instances

If you use the function-name-convention of defining routes, mapping from Requests to your defined type-safe model objects is done mostly automatically, though you need to be aware of the details of the following four sub-sections.
Further more, for mapping more complex objects/bean type objects from HTML forms, it is helpful to prefix attributes of the bean on the HTML inputs with the alias/parameter name of the bean, for instance if you have a parameter "widget: Widget", the framework will first look for attributes with input name-hints starting with "widget", so you might want to name your html inputs in the style of "widget.id", "widget.name" and so on.
Form Encoded vs. JSON requests?
How does Bowler/the ParameterMapper know whether to map from reqular HTTP Form parameters, or from the JSON contents if someone potentially POST:ed/PUT a JSON object in the request? By default, again, Bowler takes care of this: if the client has sent the HTTP Header "Content-Type" with a value of "application/json", the ParameterMapper will check for the presence of a JSON object in the request on PUT and POST requests. If the header is not set, all will go on as usual, assuming parameters are mapped as if it was a form that was submitted or parameters passed in a URL.
Incidentally, this actually helps dealing with some fragility that sometimes happens with JSON REST API's, where API users are confused whether to POST form data or POST a JSON object: Bowler simply doesn't care and will happily deal with both transparently.
Optional Parameters
Passing null is a bad thing, as it can cause NullPointerExceptions further down, making errors harder to track down. To deal with this, Bowler simply prohibits the ParameterMapper from mapping requests to null when parameters cannot be properly mapped, and will throw an Exception at the point of mapping. To deal with this case, and in the case of parameters that may occur but are not mandatory, ie optional parameters, you should simply use the Scala Option-construct:
Lookup Complex Objects by Id: StringValueTransformers
You might wonder how Bowler does the magic and looks up eventually pre-existing objects by id, maps to dates, decimals, integers, longs etc.
There is a two step approach to this:
  • You should implement a StringValueTransformer for each object type that you want to map to from Requests
  • You must register said StringValueTransformer with a TransformerRegistry in the bootstrap-class
Here's an example of a typical StringValueTransformer: As you can see, the contract is simple: if an object can be mapped, return it wrapped in a Some(), if it cannot be mapped, or an error occurs that is related to mapping, return "None".
To enable the transformer and register it with the app, add something similar to the following into your application bootstrap class:
Creating & Editing instances: PUT & POST vs. GET & DELETE
It is important to distinguish between the behavior of PUT & POST vs. GET & DELETE with the ParameterMapper:
PUT and POST requests can create new objects without a hit in a StringValueTransformer, as you'd expect, because a type persisted in a database has obviously cannot be looked up by id if it is just about to be created.
PUT and POST allows creation of new objects even though a StringValueTransformer is unable to look it up. PUT and POST are also allowed to change the values of properties of a more complex object.
GET and DELETE however are NOT allowed to create new objects nor mutate the properties of more complex objects. They are only allowed to be looked up based on registered transformers. The reason for this is simple: it is in accordance and in keeping with RESTful principles: only PUT and POST are allowed to change existing objects or create new ones. GET and DELETE are for retrieving a resource or deleting it. Of course you could circumvent this by explicitly changing values after mapping in your own code, but in most cases this would likely be a very bad idea.
Mapping with Scalatra-style Routes
If you use the Scalatra-style type-safe routes rather than the function-name convention routes, mapping from a Bowler Request to a type-safe object requires an extra step that is done automatically when using function-name convention: All you need to do is have your controller (or other class taking a request) extend the ParameterMapper trait, pass the generic type you want to transform into, and voila! You have your bean strongly typed.
It's also worth noting that the mapRequest-function can take more than one generic type, thus mapping more beans/parameters from a single request. However, mapping more than one parameter from a single Request can involve potential conflicts, so there are two ways to resolve these:
  • Provide the mapRequest function with a "nameHint" Stirng or List of "nameHints" Strings to hint to the mapRequest the names of the relevant parameters in the order they are defined. For obvious reasons this works best with simpler types that only require a single request parameter to be mapped.
  • Prefix the parameters/form-field names form the calling location with the alias-name of the type, for instance the "id" for a Widget may have a form input name of "widget.id". This is the recommended approach when dealing with multiple more complex objects that need several parameters to be properly mapped.

Validation

For validation, we need to extend the Validations trait and use the validate(){} block as seen below: ..now you can see we're starting to put everything together:
  • We map a request into a Widget
  • Validate the Widget
  • Create the Widget, then render it
The validate-block used in the example below has a simple contract: return a Option[List[Tuple2[String, String]]], whereby:
  • None means there are no validation errors.
  • Some containing a non-empty List[Tuple2[String, String]] means there where validation errors
    • The first String in the Tuple is the property key, like "id", "name" or the like
    • The second String in the Tuple is the actual error message to be displayed back
The validation handling doesn't really care what validation framework you use as long as you follow the contract, you could write manual validation code if you wanted to, however, you probably don't want to, which is why Bowler has a sensible default validation framework:
Validators & Creating Custom Validators
As Recursivity Commons (same author as Bowler) is a dependency of Bowler and contains a simple validation support, this can be used with Bowler with ease. Consider the following code: The DefaultModelValidator is a convenience class for adding all the validations that belong together for a single validation context. You may add any number of Recursivity Validators to a DefaultModelValidator, or extend the class.
If you want to implement your own validators, it is as simple as implementing the com.recursivity.commons.validator.Validator interface: The custom validator above simply takes a function/closure that returns a Long as a constructor argument, then uses the function to get a Long, which is used to check if a Widget already exists or not.
The getKey and getReplaceModel functions have to do with validation messages, which we will get to in a second (normally you'd probably want to set the key returned from the constructor rather than hard-code it).
Validation Messages & Localisation
If you look at the previous WidgetValidator example above, you can see that the DefaultModelValidator takes a classOf "WidgetValidator" as an argument. What this tells the DefaultModelValidator is the context/location of the properties file where validation error messages can be resolved. For instance:
If WidgetValidator is org.bowlerframework.examples.WidgetValidator we would need a properties file on the classpath at /org/bowlerframework/examples/WidgetValidator.properties that contains validation messages.
A typical Validation error message properties file might look as follows for the WidgetValidator example: The rules for validator properties files are quite simple:
  • A message for a validator will be keyed by the class-name of the validator, less package
  • The "key" in the validator is used to look up the property name, such as "yearMade" becoming "Year Made" in the final error message
  • The "replaceModel" defined in the validator is used to replace values such as the "{min}" and "{max}" for the number validators to give more information on the exact validation constraints
Finally a word on localisation: the validation message properties files support validation, if you create a file called WidgetValidator_se.properties, this will be the preferred source of messages for any client that has a locale set to Swedish.
Default Validators for Models
If you don't want to duplicate validation code for models that you know will always have approximately the same validation, you can add and register default ModelValidatorBuilders for a model type: A ModelValidatorBuilder is a class that you define, that has an initialize function, which takes a model of the type you define, and returns a ModelValidator. A ModelValidator in turn is grouping of Validators with a validate-function, which will run all validators. A ModelValidator can also have Validators added to it, which is the purpose of the ModelValidatorBuilders initialize function - to add all the validators to the current model under validation: If you then want to access your ModelValidator, you can either just instantiate a ModelValidatorBuilder directly and call initialize, or you can use the apply function of the ModelValidatorBuilder companion object to retrieve the appropriate ModelValidatorBuilder (if there is one): Now, just validate away to your hearts content!
Validation Errors and JSON
For JSON Validation errors the default behavior of the Bowler JsonViewRenderer is to throw an HTTP 400 error, together with a ValidationException.
If you want to render something more meaningful for the HttpExceptions than the servers default error messages, you should override your Servlet Containers default behavior for dealing with Exceptions. If you are using Jetty the way to do this is implementing a Custom error handler class and making the appropriate reference in your web.xml, you can then retrieve the validation messages from the ValidationException and render the appropriate JSON response together with the HTTP 400 error.

Forms

When editing or creating new, it's recommended that you pass object you are editing, or wanting to create into the render function (as an empty object as below if necessary): If you combine the above with the following template given the Widget case class Widget(id: Long, name: String, priceInPence: Int): It's pretty straightforward, but we can note a few things:
  • validationErrors: This template block is used to render any validation errors that may occur after submission if validation fails. This would be empty to begin with.
  • We have given the form fields the "alias hint", by prefixing the input names with "widget", though not necessary in this case, it makes life easier for the mapper if we had more objects to map than just the widget
  • Even though we know the widget bean is initially empty, we still set the values of the fields to the properties of the widget. This is so that we can retain form-state if validation was to fail on posting the form.
If there are object relationships to deal with in a form, you could obviously deal with this with the use of StringValueTransformers as described in the section Lookup Complex Objects by Id: StringValueTransformers.

Important! Even if you create new objects that have synthetic keys, such as incrementing numbers, having an id as a hidden field in your form, assigned to something like "0" will save you a lot of pain when the ParameterMapper tries to map a value to your id field. Most ORM's/persistence frameworks will assign a new value on insert anyway.

The Request Cycle

Intercepting Requests (example: transactionality)

Intercepting requests in a catch-all function can be a useful thing for many types of scenarios, for instance transaction-management with persistence, or cleaning up other resources to avoid having developers call ".close()" functions all over the code. This is catered for in Bowler quite easily by extending the InterceptingController trait. The example below shows an example of transaction- and connection management in the InterceptingController "around"-function as used by the Bowler Squeryl mapper module: The "controller"-function received as an argument in this case is simply the actual function/closure you defined as your request-handler in a get(..), post(..), put(..) or delete(..) block. To proceed to your normal request processing it needs to be called in your around-function.

Nested Interception(example: transactionality + authentication/authorization)

But what if I want to add something in a sub-class to the above example that needs to run inside the transaction, but around the controller-function? Easy, just override "around", define an anonymous function with the correct signature ((Request, Request) => Unit ) and call the controller-function from within it as in the example below: This example shows how to easily add authentication that would run inside the transactional block, but before and after the actual request-handling, this giving you control whether for instance you actually want to run the default request handling, or perhaps re-direct to something like a login page if it is a authentication/authorization use case.

Persistence Integration

Bowler has a flexible persistence integration framework available in add-on modules/sbt/maven dependencies. In most cases adding a new persistence integration is as simple as implementing the Bowler Dao-trait and extending the InterceptingController-trait to do transaction management. The Bowler persistence integration in most cases uses a "Open Session in View" style pattern, which simply opens a connection and transaction on the beginning of a request, and closes and commits it at the end (or does a rollback in an Exception). The example below shows the InterceptingController integration for Squeryl: As you can see, it's pretty straightforward. If you want to add additional things, like authentication, authorization or other checks around a request, but inside a transaction, you can just follow the pattern that we described in the Intercepting Requests section.
Finally, it is worth noting though that the Bowler Persistent Mapper framework does not assume a relational database - in theory any persistent store should work!

Squeryl

Squeryl is an excellent Scala based ORM/persistence framework which gives you a number of benefits over Java persistence frameworks like Hibernate and JPA. I quite like it. To set up a project with the Squeryl module, add the dependencies described in the Squeryl Build to your project.
Once you have done so, you need to set-up your datasource, you can do this programmatically in your Bootstrap if you want, below is an example with C3P0 connection pooling: Once you have done this setup, in most cases you can just extend the org.bowlerframework.squeryl.SquerylController trait!
You may also want to use some of the generic Squeryl DAO's for simple CRUD like functionality, or with some of the Persistence Helpers described later. The Squeryl module has an abstract SquerylDao, which in turn can be extended, and is extended by: For how to use Squeryl specifically in more debt, please refer to the Squeryl site.

Jpa

The JPA integration module follows exactly the same pattern as the Squeryl integration, in that you simply setup your JPA persistence.xml as you would otherwise, then extend the JpaController trait in most cases. If/when you want to access a JPA EntityManager anywhere in your code that is running directly or indirectly inside a JpaController, your EntityManagers are just one import away: One thing here is of course that to access EntityManagers without providing a persistence-unit name, you need to set a default name in the com.recursivity.jpa.PersistenceUnit.unitName object variable.
If you want to use any of the Persistence Helper detailed next, the JPA integration only has one Dao to worry about (but you can extend/override parts of it of course): JpaDao

Persistence Helpers

The Persistence Mapper modules have the following generic persistence helpers which are independent of the persistence implementation, such as JPA or Squeryl:
EntityTransformer (StringValueTransformer)
As we have previously mentioned, StringValueTransformers are a useful way to ensure you can transform simple request parameters such as id's transparently into more complex objects. This becomes even more important when dealing with persistent objects, and or objects that have persistent objects set on them via id from a dropdown list.
Below is an example of how to re-use the generic org.bowlerframework.persistence.EntityTransformer to enable lookups of a Car domain model object with the help of Jpa: This code would typically go into your bootstrap class, or some other part where the transformer is registered with the TransformerRegistry before it is needed.
As you can see, the EntityTransformer uses generics, so should be usable for most types of persistent objects provided you have a Dao implementation to provide the transformer.
UniqueEntityValidator
The org.bowlerframework.persistence.UniqueEntityValidator is a Validator that checks that an Entity is unique in a persistent store - probably useful if you have resources where the user assigns an id!
CRUD Controller
The Bowler Persistence Mapper framework also provides a simple org.bowlerframework.persistence.CrudController if you have simple needs that just consist of, well, Create, Read, Update and Delete. You would typically set it up in the following way in your bootstrap (example with Squeryl): As you can see, it takes type parameters of the entity type and its key-type. In addition it takes a persistence controller (in this case Squeryl), a Dao implementation and a resource name as arguments. The resourcename "people" will in this case mean that the root of the controller will be at "/people/".
The reason the CRUD controller takes another Controller as an argument is that it is actually only a proxy for a controller and not a controller itself: The CRUD controller will initialize the provided controller with the correct business logic.
The CRUD controller does the following things:
  • GET /[resource]/: gets the first n elements of type T (n defaults to 10)
  • GET /[resource]/?itemsInList=n: gets the n first elements of type T, changes n default to provided parameter
  • GET /[resource]/page/2: get's second page of paginated list of elements as above
  • GET /[resource]/:id : displays the T with the id provided
  • GET /[resource]/new : should return a create form that POSTs a new T to /
  • GET /[resource]/:id/edit : should return an edit form that POSTs an updated T to /:id
  • DELETE /[resource]/:id : Deletes the T with the provided id
  • POST /[resource]/: Creates a new entity of type T and renders it
  • POST /[resource]/:id: Updates an entity of type T with the provided id and renders it

Testing

Testing can be done both in an "in-vm container" using ScalatraFunSuite like this, or completely without any dependencies on even a mock container.
[TESTING SECTION TO BE EXPANDED]