- Play Framework Essentials
- Julien Richard Foy
- 849字
- 2021-08-05 17:47:44
Play – a framework used to write web applications
Play is a framework used to write web applications. As shown in the following diagram, a web application is based on a client-server architecture and uses the HTTP protocol for communication:

Web-oriented architecture
Users have the role of clients and make HTTP requests to servers to interact with the application. The servers process their requests and send them a response. Along the way, the web application might need to make use of various databases or perhaps other web services. This entire process is depicted in the following diagram:

The Play framework's overall architecture
This book will show you how Play can help you to write such web applications. The preceding diagram shows a first big picture of the framework's overall architecture. We will refine this picture as we read through this book, but for now it is a good start. The diagram shows a web client and a Play application. This one is made of a business layer (on the right), which provides the services and resources specific to the application. These features are exposed to the HTTP world by actions, which themselves can be logically grouped within controllers. Gray boxes represent the parts of code written by the developer (you!), while the white box (the router) represents a component already provided by Play.
HTTP requests performed by the client (1) are processed by the router that calls the corresponding action (2) according to URL patterns you configured. Actions fill the gap between the HTTP world and the domain of your application. Each action maps a service or resource of the business layer (3) to an HTTP endpoint.
All the code examples in this book will be based on a hypothetical shopping application allowing users to manage and sell their items. The service layer of this application is defined by the following Shop
trait:
case class Item(id: Long, name: String, price: Double) trait Shop { def list(): Seq[Item] def create(name: String, price: Double): Option[Item] def get(id: Long): Option[Item] def update(id: Long, name: String, price: Double): Option[Item] def delete(id: Long): Boolean }
In Java, the service layer is defined by the following Shop
interface:
public class Item { public final Long id; public final String name; public final Double price; public Item(Long id, String name, Double price) { this.id = id; this.name = name; this.price = price; } } interface Shop { List<Item> list(); Item create(String name, Double price); Item get(Long id); Item update(Long id, String name, Double price); Boolean delete(Long id); }
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The Item
type simply says that an item has a name, a price, and an ID. The Shop
type defines the typical Create, Read, Update, and Delete (CRUD) operations we want to do. Connecting with the figure that shows the architecture of Play applications, these types represent the business layer of your web service and their definition should live in a models
package in the app/
source directory. The remainder of this chapter explains how to write a controller exposing this business layer via HTTP endpoints using JSON to represent the data.
As an example, here is a possible minimalist Scala implementation of the Shop
trait:
package models import scala.collection.concurrent.TrieMap import java.util.concurrent.atomic.AtomicLong object Shop extends Shop { private val items = TrieMap.empty[Long, Item] private val seq = new AtomicLong def list(): Seq[Item] = items.values.to[Seq] def create(name: String, price: Double): Option[Item] = { val id = seq.incrementAndGet() val item = Item(id, name, price) items.put(id, item) Some(item) } def get(id: Long): Option[Item] = items.get(id) def update(id: Long, name: String, price: Double): Option[Item] = { val item = Item(id, name, price) items.replace(id, item) Some(item) } def delete(id: Long): Boolean = items.remove(id).isDefined }
This implementation stores the data in memory, so it loses everything each time the application restarts! Nevertheless, it is a sufficient business layer basis, letting us focus on the web layer. The implementation uses a concurrent collection to solve concurrency issues. Indeed, as I will explain later, the code called by the controllers must be thread safe.
For Java developers, here is a minimalist implementation of the Shop
interface:
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.atomic.AtomicLong; new Shop() { SortedMap<Long, Item> items = new ConcurrentSkipListMap<>(); AtomicLong seq = new AtomicLong(); @Override public Collection<Item> list() { return new ArrayList<>(items.values()); } @Override public Item create(String name, Double price) { Long id = seq.incrementAndGet(); Item item = new Item(id, name, price); items.put(id, item); return item; } @Override public Item get(Long id) { return items.get(id); } @Override public synchronized Item update(Long id, String name, Double price) { Item item = items.get(id); if (item != null) { Item updated = new Item(id, name, price); items.put(id, updated); return updated; } else return null; } @Override public Boolean delete(Long id) { return items.remove(id) != null; } };
As previously mentioned, the code called by controllers must be thread safe, hence the use of Java concurrent collections.
- Spring 5.0 By Example
- Python網絡爬蟲從入門到實踐(第2版)
- Swift 3 New Features
- Python編程完全入門教程
- Java程序設計:原理與范例
- Apache Spark 2.x for Java Developers
- 詳解MATLAB圖形繪制技術
- 一本書講透Java線程:原理與實踐
- CRYENGINE Game Development Blueprints
- Web App Testing Using Knockout.JS
- UML基礎與Rose建模實用教程(第三版)
- Wearable:Tech Projects with the Raspberry Pi Zero
- 讓Python遇上Office:從編程入門到自動化辦公實踐
- 面向對象分析與設計(第3版)
- Swift 2 Blueprints