This post is a review of Julien Richard-Foy's recently published Play Framework Essentials (Packt Publishing). Play Framework Essentials consists of seven chapters and approximately 180 pages of substantive content. The book's subtitle is, "An intuitive guide to creating easy-to-build scalable web applications using the Play framework."
Preface
The Preface of most Packt Publishing books is a great place to start when trying to decide whether to read a Packt Publishing book. This is because the Packt Publishing Prefaces, including the Preface of Play Framework Essentials, frequently summarize each of the chapters of the book (one to three sentences per chapter in this case), describe what is needed for using the book's examples (Play 2.3.x, JDK 6 or newer, and a web browser in this case), and who the target audience is ("Java or Scala developers who already have some knowledge of web development" in this case).
Chapter 1: Building a Web ServiceWith a title that include the word "essentials", one might expect the book to be light of "fluffy" text and this is the case with Play Framework Essentials. The initial chapter of Play Framework Essentials starts off fast with a very brief description of what the Play Framework is before diving immediately into the first example that shows the Scala and Java versions of the service layer. The chapter then explains how to bootstrap a Play Framework application with Typesafe Activator.
The remainder of the chapter demonstrates building a simple application with the Play Framework. Along the way, the chapter introduces sbt (described as "a build tool for Scala projects"), Human-Optimized Config Object Notation (HOCON) for configuration, URL routing in Play, curl (for testing connectivity to session via HTTP), building HTTP responses with HTTP status codes, serializing data in JSON (includes mention of significant differences between implementing in Java or Scala), reading JSON data, validating JSON data.
Chapter 2: Persisting Data and TestingChapter 2 of Play Framework Essentials begins with a coverage of Play's support for integrated testing with specs2 (Scala) and JUnit (Java). There is a section that describes Play's use of Scala's reverse routing. The test-focused portion of the second chapter ends with discussion regarding effective writing of HTTP tests and "running a fake Play application."
The second half of Play Framework Essentials's second chapter is focused on database persistence with specific focus on use of Play's JDBC plugin and JPA plugin. After looking at use of JDBC-based persistence, the chapter moves to coverage of using Slick (Scala) and JPA (Java).
Part of Chapter 2's coverage of database persistence with Play discusses use of GlobalSettings to use startup of a Play application to enable database fixtures. Play's database evolutions support is also covered. Chapter 2 concludes with a section on using H2 as an in-memory database for testing code related to relational databases.
Chapter 3: Turning a Web Service into a Web ApplicationThe third chapter of Play Framework Essentials is about building a web application with user interface from a web service. The chapter introduces the template engine Twirl and provides several examples of syntax and constructs used with the template.
The middle portion of Chapter 3 deals with HTML forms. In particular, it covers generation of forms and reading and validating form data. Discussion touches on Play's HTML helpers and how these can be customized. The chapter's section on form validation specifically covers both the Java validation API and the Scala validation API. The chapter introduces Scala-based content negotiation and provides examples of how to write "some helper functions similar to the Scala content negotiation API" for Java.
Play Framework Essentials's third chapter concludes with an introduction of Selenium as an approach to "programmatically drive a web browser" and an introduction of FluentLenium as "a library that provides a fluent interface for the [Selenium] WebDriver." This section of the chapter demonstrates their use with Java and Scala to test the web interface.
Chapter 4: Integrating with Client-side TechnologiesChapter 4 of Play Framework Essentials continues from where Chapter 3 left off. While Chapter 3 discussed converting web services into web applications, Chapter 4 covers integrating traditional web client-side technologies with the applications built on top of the Play framework. The author points out an interesting observation regarding Play and these client-side technologies: "The Play framework essentially focuses on the server-side part of your application and gives you freedom on which client-side technology to use." Chapter 4 focuses on the features that Play does provide to assist with the development of the client.
The first client-side-supporting feature of Play discussed in Chapter 4 is serving of static (or public) assets. JavaScript reverse routing is another Play feature covered in this chapter.
The fourth chapter introduces sbt-web as "an sbt plugin family" that "can manage ... processing steps" such as generating JavaScript from higher-level languages (sbt-coffeescript and sbt-less) and concatenating (sbt-rjs), minifying (sbt-uglify), and compressing (sbt-gzip) code. It demonstrates examples of each of these functions implemented using an sbt plugin. The chapter also discusses using sbt-web plugin's support of WebJars as "a repository of client-side artifacts" and using the sbt-mocha plugin to "run Mocha tests from the sbt test runner."
Play Framework Essentials's fourth chapter ends with a more substantial "Summary" section than one typically sees in books. In fact, it includes a useful graphical representation of how the plugins covered in the chapter fit together is the "assets processing pipeline."
Chapter 5: Reactively Handling Long-running RequestsChapter 5 of Play Framework Essentials "presents the challenges of stream processing and the way the Play framework solves them." The chapter begins by referencing Benjamin Erb's diploma thesis Concurrent Programming for Scalable Web Architectures and introducing Play's "evented execution model." The author explains how the Scala model can be better, but warns that caution needs to be used to explicitly ensure that threads are not blocked. He introduces Play's support for Scala's Future API to allow for asynchronous blocks. The author also describes the need to use a distinct execution context to handle blocking functionality such as JDBC interaction with a relational database. This section is also useful because it introduces and briefly explains Akka.
Another significant section of Chapter 5 introduces Iteratee, which the author describes as "an incremental computation" and which he warns should be used only with Scala (not with Java). Enumerators are introduced by comparing them to iteratees: "Streaming results using enumerators Iteratees make it possible to consume streams of data in a non-blocking way. Conversely, enumerators produce data streams in a non-blocking way."
The Summary of Chapter 5 states, "This chapter detailed a lot of things on the internals of the framework." That might be an understatement. There is a lot of detailed description of the internal workings of the Play Framework in this chapter. I felt like this chapter really points out some of the distinguishing features of Play.
Chapter 6: Leveraging the Play Stack – Security, Internationalization, Cache, and the HTTP ClientPlay Framework Essentials's sixth chapter begins by articulating the topics covered in the chapter: security (authentication, cross-site scripting, cross-site request forgery, HTTPS), cache, internationalization, and HTTP client. The section of authentication explains and illustrates using Java and Scala examples how Play supports session scope/cookies in conjunction with authentication. The sections on cross-site scripting (XSS) and cross-site request forgery (CSRF) explain tactics that can be used to avoid those vulnerabilities.
The portion of Chapter 6 covering CSRF delves into Play's support for HTTP request filters. It uses this introduction to Play filters to look at Play's CSRF Filter, which is described as a filter that "automatically checks that the CSRF token of a form submission corresponds to the one in the client's session."
Chapter 6's section on HTTPS states that Play's default is to "use only HTTP." This section then demonstrates configuring HTTPS via system property specification.
Chapter 6 describes Play's cache support (which is built upon Ehcache): "Play provides a minimal cache library and some controller level caching features that can help you leverage both client-side and server-side caches." The coverage of Play's cache support includes Java and Scala examples and talks about client-side and server-side caching. The chapter's discussion of Play Framework's internationalization support also covers both Scala and Java examples.
The sixth chapter concludes with sections on calling remote web services and begins with an introduction of OAuth 2.0. The chapter then proceeds to discuss how to connect to the reader's "preferred social network" using an OAuth client to call the HTTP API of the preferred social network.
Chapter 7: Scaling Your Codebase and Deploying Your ApplicationThe final chapter of Play Framework Essentials "presents common code patterns you want to use in order to keep a productive code base." The chapter begins by discussion how to apply Play's action builders to make an "action's logic reusable and composable." The chapter then goes on to discuss use of dependency injection to achieve greater modularity. An example using Guice is presented as part of this discussion on dependency injection. The section of Chapter 7 on mocking applies Mockito.
Chapter 7 also looks at separating application code into separate independent artifacts with specific focus on splitting the controller into multiple artifacts. Th chapter then moves onto deployment with brief sections on deploying to traditional infrastructure and deploying to the cloud. There is also a section on distinguishing between development and production modes using different configuration files or system properties.
General Observations- Play Framework Essentials provides examples in both Scala and Java. There are a couple of advantages of this. The first is that it allows developers to use the language they are more comfortable with or are allowed or expected to use when using Play. The second advantage is that it allows Java developers to learn more about Scala by comparing Scala examples to Java examples. The only downside is that explanations take longer when both languages are used, but I consider the value of examples in both languages greater than the cost. It is fairly easy to skip over the examples written in the language that is not of interest. I also like that the author mentions when certain features are only available in Scala or in Java.
- The code listings in Play Framework Essentials tend to be well-formatted. The biggest downside of these code listings is their lack on line numbers and the black text on white background (no color syntax highlighting).
- Play Framework Essentials includes several graphics depicting architecture and other high-level concepts. Although these generally serve their purpose of illustrating what is being described, it would have been nice to have some color in more of these in the electronic version rather than the grayscale presentation of several of them. However, these grayscale images are sharp enough that I suspect they present well in printed copies.
- Although Play Framework Essentials has under 200 pages and largely focuses on "essentials" of the Play Framework, I still felt like there was a lot of detail in this book. The book contains low-level and high-level details, but spends (or wastes, depending on your perspective) little time on introductory and historical details. All chapters are relatively technically detailed, but Chapters 5 through 7 are particularly detailed.
Play Framework Essentials does as its title suggests and introduces essential aspects of the Play Framework.