7. HTTP Routing
● URI to Controller mapping
GET /projects/:projectId/tasks controllers.Tasks.index(projectId: Long)
POST /projects/:projectId/tasks controllers.Tasks.add(projectId: Long, folder: String)
PUT /tasks/:task controllers.Tasks.update(task: Long)
DELETE /tasks/:task controllers.Tasks.delete(task: Long)
● pattern: <HTTP Method> <URI> <Controller>
8. State in Play!
● server is stateless
● state is stored on client
● session and flash scopes
○ for data that is required between subsequent HTTP
requests
○ cookie (max 4KB per User / only string values)
Important: The flash scope should only be used to transport success/error messages on
simple non-Ajax applications. As the data are just kept for the next request and because there
are no guarantees to ensure the request order in a complex Web application, the Flash scope is
subject to race conditions.
9. Model
● POJOs with generated getters/setters
● Play uses Active Record pattern
● EBean -> default ORM (JPA without
container)
10. Testing Support
● play test
● Helper classes to mock and fake almost
everything
● provides support for Selenium &
FluentLenium
15. Error Handling
● Big Plus: detailed error messages shown in
browser -> no need to search log files
● errors can be in
○ Java/Scala class
○ Routes config
○ template code
○ ….
20. Threaded
● one thread assigned to each request
● any I/O is typically synchronous
● problems that might arise?
○ thread pool sizing -> too many/too few?!
○ Thread stack size with 64 Bit JVMs -> 1MB
○ thread might get blocked, waiting for another
service to complete
22. Evented
● one thread per CPU core
● basic idea: ensure that these scarce
resources are never blocked
● I/O is asynchronous
● blocking I/O mostly when talking to DBs
24. Async Features
● idea: never block
● Play actions are async by default!
● Controllers return Result objects
● when async, return Promise<Result>
○ client is blocked - server is not blocked and serves
result when it’s computed
Note: Whether the action code returns a Result or a Promise<Result>, both kinds of returned object are
handled internally in the same way. There is a single kind of Action, which is asynchronous, and not two kinds
(a synchronous one and an asynchronous one). Returning a Promise is a technique for writing non-blocking
code.
28. Summary
● High Developer Productivity
○ make a change -> refresh -> see the change
○ hot reload for all resources
● Built-in testing support
● Predictable Scalability
○ adheres to HTTP principles
○ non-blocking I/O support
● Commercial Support available through Typesafe & Zenexity
● Typesafe
○ makes it easier for large code bases
29. Summary
● Immature
○ Best Practices aren’t well defined
○ API is changing
○ Play 2 was entirely rewritten
● Not a Servlet
○ breaks away from the Servlet spec
● Build System (SBT)
○ hard to understand (even for Scala experts)
○ very powerful & flexible, but very steep learning curve