An example web-application built around Spray and spray-servlet. With full spray-json integration too.
Scala JavaScript CSS

README.md

spray-servlet-webapp

Oh hai!

You've found my web-application example using Spray and spray-servlet 1.1-M7.

On a recent project, I spent quite a bit of time plugging together a production web-application built around Spray. Although the stand-up went fairly well, I encountered several pain points while building a "place to stand" — setting up the SBT project, figuring out how to package and serve static content, integrating Scalate templating, integrating authentication and cookie based session support, integrating JSON support, etc. I ended up piecing together bits of code and knowledge scattered about the Interwebz to get something going, and was constantly asking myself questions like, "how do I use X", "how do I integrate Y" and "where does Z go". To that end, I thought it would be helpful if I spent some time hacking out a complete "real world" Spray web-application example that addresses these questions.

The Spray documentation is excellent, and this project is intended to supplement that documentation with a complete and robust example that illustrates how a number of Spray concepts integrate into a Spray based web-application.

Note, this example project uses spray-servlet and ultimately compiles and packages the web-application into a .war file — deployable in most Servlet 3.0 containers. Of course, if you're not using a Servlet container to deploy your application, you can certainly extend the concepts herein to your server of choice — perhaps something like spray-can.

Lastly, if you have a correction or would like to contribute, pull requests are always welcome.

What this Project Covers

In this project, you'll find reasonably complete demonstrations of the following:

  • SBT "in project Servlet container" integration using the xsbt-web-plugin and Jetty 8.1.10.v20130312 (a.k.a., Jetty 8-stable). See Build.scala.

  • The spray-servlet WebBoot configuration of multiple HttpServiceActor's under a single root actor. One service actor deals with vanilla web-application requests, while another is dedicated to dealing with AJAX requests. See Boot.scala and the com.kolich.spray.service.routes package.

  • The serving and packaging of static web-application content: images, JavaScript, and CSS. As far as I can tell, the Spray default mechanism for serving static content involves packaging such resources into a .jar file, and consequently serving static content from that .jar on the classpath. This became frustrating very quickly when I realized, for example, that I could not simply modify a JavaScript file and refresh my browser to see the change — because static content was bundled into a resource .jar I had to stop my application and restart the JVM to see any local changes. This was a showstopper for rapid development, so I gave up and figured out how to use the Servlet container's default servlet to serve static content instead. I did try tools like sbt-revolver, but that failed miserably (I probably just didn't know what I was doing). See public.

  • Full Scalate templating support, which demonstrates how to use Scalate templates to render out "dynamic" HTML pages. And, how to pass data from your Spray routes to a Scalate template. See ScalateSupport.scala and templates.

  • Straightforward user authentication using Spray's authenticate directive with cookie based session support. Like you would expect, the user has to be "logged in" to access specific paths and content, which is managed here using session cookies and an in-memory session map. See the com.kolich.spray.auth package.

  • Realistic JSON support, which demonstrates how to use spray-json to unmarshall JSON into case classes (on requests), and marshall case classes back into JSON (for responses). See the com.kolich.spray.protocols package.

Bootstrap

This project is built and managed using SBT 0.12.2.

To clone and build this project, you must have SBT installed and configured on your computer.

To start, clone the repository.

#~> git clone git://github.com/markkolich/spray-servlet-webapp.git

Run sbt from within your newly cloned spray-servlet-webapp directory.

#~> cd spray-servlet-webapp
#~/spray-servlet-webapp> sbt
...
spray-servlet-webapp:1.0>

You will see a spray-servlet-webapp SBT prompt once all dependencies are resolved and the project is loaded.

In SBT, run container:start to start the local Servlet container. By default the server listens on port 8080.

spray-servlet-webapp:1.0> container:start
[info] jetty-8.1.10.v20130312
[info] Started SelectChannelConnector@0.0.0.0:8080

In your nearest web-browser, visit http://localhost:8080/spray and you should see the login page prompting you for a username and password.

To stop the development server, run container:stop.

See the xsbt-web-plugin wiki for all of the gory details on managing the development servlet container from SBT.

To build a deployable WAR for your favorite Servlet container, run package in SBT.

spray-servlet-webapp:1.0> package
...
[info] Compiling 20 Scala sources to ~/spray-servlet-webapp/target/classes...
[info] Packaging ~/spray-servlet-webapp/dist/spray-servlet-webapp-1.0.jar ...
[info] Done packaging.
[info] Packaging ~/spray-servlet-webapp/dist/spray-servlet-webapp-1.0.war ...
[info] Done packaging.

Note the resulting WAR is placed into the spray-servlet-webapp/dist directory. Deploy and enjoy.

To create an Eclipse project, run eclipse in SBT.

spray-servlet-webapp:1.0> eclipse
...
[info] Successfully created Eclipse project files for project(s):
[info] spray-servlet-webapp

You'll now have a real Eclipse .project file worthy of an Eclipse import. Note your new .classpath file as well — all source JAR's are fetched and injected into the Eclipse project automatically.

Licensing

Copyright (c) 2013 Mark S. Kolich

All code in this project is freely available for use and redistribution under the MIT License.

See LICENSE for details.