Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Play Framework essentials
Play Framework essentials

Play Framework essentials: An intuitive guide to creating easy-to-build scalable web applications using the Play framework

eBook
$9.99 $19.99
Paperback
$32.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Play Framework essentials

Chapter 1. Building a Web Service

This chapter will cover the following topics:

  • Bootstrapping a Play project
  • Understanding the different pieces of a Play project
  • Mapping URLs to your service entry points
  • Serving JSON responses and reading and validating JSON requests

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:

Play – a framework used to write web applications

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:

Play – a framework used to write web applications

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.

Bootstrapping a Play application

While it is totally possible to start a Play project from nothing, you might find it more convenient to start from an empty application skeleton and set up the build system to depend on Play so that you can directly focus on the code of your application.

Typesafe Activator (https://typesafe.com/activator) can be used to generate such an empty application skeleton. This tool lists several application templates designed to be used as the project's starting point. Actually, Activator does a bit more than this: it can also compile and run your project and even provide a minimalist development environment with a code editor right in your web browser!

Let's start with a basic Scala or Java application. Download and install Activator by referring to its documentation. Though some templates already support advanced features out of the box, we will begin with a completely empty application and will progressively enhance it with new features (for example, persistence or client-side technologies).

In a *nix terminal, create a new application skeleton by running the following activator command:

$ activator new

You will be asked which application template to use; choose just-play-scala (or just-play-java to create a Java application). Give the application the name shop.

A new directory, shop/, has been created that contains the application's code. Go to this directory and execute the activator run command:

$ cd shop
$ activator run

Activator starts a development HTTP server listening (by default) on port 9000. In your browser, go to http://localhost:9000 to test it; the HTTP server compiles your application, starts it, and processes your HTTP request. If everything works fine, your browser should show a page titled Just Play Scala (or Just Play Java).

You can stop the running application with Ctrl + D.

You can also start Activator without passing it a command name:

$ activator

In such a case, you enter in the project sbt shell, where you can manage the life cycle of your project as in any sbt project. For instance, you can try these commands: clean, compile, run, and console. The last one starts a REPL where you can evaluate expressions using your application's code.

Note

sbt is a build tool for Scala projects. Check out http://www.scala-sbt.org for more details.

Play applications' layout

To explain why you get this result in your browser when you ran the application, let's have a look at the files created by the activator new command. Under the project root directory (the shop/ directory), the build.sbt file describes your project to the build system.

It currently contains a few lines, which are as follows:

name := """shop"""

version := "1.0-SNAPSHOT"

lazy val root = project.in(file(".")).enablePlugins(PlayScala)

The first two lines set the project name and version, and the last line imports the default settings of Play projects (in the case of a Java project, this line contains PlayJava instead of PlayScala). These default settings are defined by the Play sbt plugin imported from the project/plugins.sbt file. As the development of a Play application involves several file generation tasks (templates, routes, assets and so on), the sbt plugin helps you to manage them and brings you a highly productive development environment by automatically recompiling your sources when they have changed and you hit the reload button of your web browser.

Though based on sbt, Play projects do not follow the standard sbt projects layout: source files are under the app/ directory, test files under the test/ directory, and resource files (for example, configuration files) are under the conf/ directory. For instance, the definitions of the Shop and Item types should go into the app/ directory, under a models package.

After running your Play application, try changing the source code of the application (under the app/ directory) and hit the reload button in your browser. The development HTTP server automatically recompiles and restarts your application. If your modification does not compile, you will see an error page in your browser that shows the line causing the error.

Let's have a deeper look at the files of this minimal Play application.

The app/ directory, as mentioned before, contains the application's source code. For now, it contains a controllers package with just one controller named Application. It also contains a views/ directory that contains HTML templates. We will see how to use them in Chapter 3, Turning a Web Service into a Web Application.

The conf/ directory contains two files. The conf/application.conf file contains the application configuration information as key-value pairs. It uses the Human Optimized Configuration Object Notation syntax (HOCON; it is a JSON superset, check out https://github.com/typesafehub/config/blob/master/HOCON.md for more information). You can define as many configuration points as you want in this file, but several keys are already defined by the framework to set properties, such as the language supported by the application, the URL to use to connect to a database, or to tweak the thread pools used by the application.

The conf/routes file defines the mapping between the HTTP endpoints of the application (URLs) and their corresponding actions. The syntax of this file is explained in the next section.

URL routing

The routing component is the first piece of the framework that we will look at:

URL routing

URL routing

The preceding diagram depicts its process. It takes an HTTP request and calls the corresponding entry point of the application. The mapping between requests and entry points is defined by routes in the conf/routes file. The routes file provided by the application template is as follows:

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET     /                 controllers.Application.index

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file     controllers.Assets.versioned(path="/public", file)

Apart from comments (starting with #), each line of the routes file defines a route associating an HTTP verb and a URL pattern to a controller action call.

For instance, the first route associates the / URL to the controllers.Application.index action. This one processes requests by always returning an HTTP response with a 200 status code (OK) and an HTML body that contains the result of the rendering of the views.html.index template.

The content of the routes file is compiled by the sbt plugin into a Scala object named Router and contains the dispatching logic (that is, which action to call according to the incoming request verb and URL). If you are curious, the generated code is written in the target/scala-2.10/src_managed/main/routes_routing.scala file. The router tries each route, one after the other, in their order of declaration. If the verb and URL match the pattern, the corresponding action is called.

Your goal is to expose your Shop business layer as a web service, so let's add the following lines to the routes file:

GET    /items        controllers.Items.list
POST   /items        controllers.Items.create
GET    /items/:id    controllers.Items.details(id: Long)
PUT    /items/:id    controllers.Items.update(id: Long)
DELETE /items/:id    controllers.Items.delete(id: Long)

The first route will return a list of items for sale in the shop, the second one will create a new item, the third one will show detailed information about an item, the fourth one will update the information of an item, and finally, the last one will delete an item. Note that we follow the REST conventions (http://en.wikipedia.org/wiki/REST) for the URL shapes and HTTP verbs.

In the controllers package of your code, add the following Items controller that matches the added routes:

package controllers

import play.api.mvc.{Controller, Action}

object Items extends Controller {
  val shop = models.Shop // Refer to your Shop implementation
  val list = Action { NotImplemented }
  val create = Action { NotImplemented }
  def details(id: Long) = Action { NotImplemented }
  def update(id: Long) = Action { NotImplemented }
  def delete(id: Long) = Action { NotImplemented }
}

The equivalent Java code is as follows:

package controllers;

import play.mvc.Controller;
import play.mvc.Result;

public class  Items extends Controller {

  static final Shop shop = Shop.Shop; // Refer to your Shop implementation

  public static Result list() {
    return status(NOT_IMPLEMENTED);
  }
  public static Result create() {
    return status(NOT_IMPLEMENTED);
  }
  public static Result details(Long id) {
    return status(NOT_IMPLEMENTED);
  }
  public static Result update(Long id) {
    return status(NOT_IMPLEMENTED);
  }
  public static Result delete(Long id) {
    return status(NOT_IMPLEMENTED);
  }
}

Each route is mapped by a controller member of type Action (or in Java, a public static method that returns a Result). For now, actions are not implemented (they all return NotImplemented) but you will progressively connect them to your Shop service so that, for instance, the Items.list action exposes the shop list method.

Route path parameters

In our example, in the first route, the URL pattern associated with the controllers.Items.details action is /items/:id, which means that any URL starting with /items/ and then containing anything but another / will match. Furthermore, the content that is after the leading / is bound to the id identifier and is called a path parameter. The /items/42 path matches this pattern, but the /items/, /items/42/0, or even /items/42/ paths don't.

When a route contains a dynamic part such as a path parameter, the routing logic extracts the corresponding data from the URL and passes it to the action call.

You can also force a path parameter to match a given regular expression by using the following syntax:

GET     /items/$id<\d+>    controllers.Items.details(id: Long)

Here, we check whether the id path parameter matches the regular expression \d+ (at least one digit). In this case, the /items/foo URL will not match the route pattern and Play will return a 404 (Not Found) error for such a URL.

A route can contain several path parameters and each one is bound to only one path segment. Alternatively, you can define a path parameter spanning several path segments using the following syntax:

GET     /assets/*file        controllers.Assets.at(path = "/public", file)

In this case, the file identifier captures everything after the /assets/ path segment. For instance, for an incoming request with the /assets/images/favicon.png URL, file is bound to images/favicon.png. Obviously, a route can contain at most one path parameter that spans several path segments.

Parameters type coercion

By default, request parameters are coerced to String values, but the type annotation id: Long (for example, in the details route) asks Play to coerce the id parameter to type Long. The routing process extracts the content corresponding to a parameter from the URL and tries to coerce it to its target type in the corresponding action (Long in our example) before calling it.

Note that /items/foo also matches the route URL pattern, but then the type coercion process fails. So, in such a case, the framework returns an HTTP response with a 400 (Bad Request) error status code.

This type coercion logic is extensible. See the API documentation of the QueryStringBindable and PathBindable classes for more information on how to support your own data types.

Parameters with fixed values

The parameter values of the called actions can be bound from the request URL, or alternatively, can be fixed in the routes file by using the following syntax:

GET     /          controllers.Pages.show(page = "index")
GET     /:page     controllers.Pages.show(page)

Here, in the first route, the page action parameter is set to "index" and it is bound to the URL path in the second route.

Query string parameters

In addition to path parameters, you can also define query string parameters: parameters extracted from the URL query string.

To define a query string parameter, simply use it in the action call part of the route without defining it in the URL pattern:

GET     /items          controllers.Items.details(id: Long)

The preceding route matches URLs with the /items path and have a query string parameter id. For instance, /items and /items?foo=bar don't match but /items?id=42 matches. Note that the URL must contain at least all the parameters corresponding to the route definition (here, there is only one parameter, which is id), but they can also have additional parameters; /items?foo=bar&id=42 also matches the previous route.

Default values of query string parameters

Finally, you can define default values for query string parameters. If the parameter is not present in the query string, then it takes its default value. For instance, you can leverage this feature to support pagination in your list action. It can take an optional page parameter defaulting to the value 1. The syntax for default values is illustrated in the following code:

GET   /items        controllers.Items.list(page: Int ?= 1)

The preceding route matches the /items?page=42 URL and binds the page query string parameter to the value 42, but also matches the /items URL and, in this case, binds the page query string parameter to its default value 1.

Change the corresponding action definition in your code so that it takes a page parameter, as follows:

def list(page: Int) = Action { NotImplemented }

The equivalent Java code is as follows:

public static Result list(Integer page) {
  return status(NOT_IMPLEMENTED);
}

Trying the routes

If you try to perform requests to your newly added routes from your browser, you will see a blank page. It might be interesting to try them from another HTTP client to see the full HTTP exchange between your client and your server. You can use, for example, cURL (http://curl.haxx.se/):

$ curl -v http://localhost:9000/items
> GET /items HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9000
> Accept: */*
>
< HTTP/1.1 501 Not Implemented
< Content-Length: 0
<

The preceding command makes an HTTP GET request on the /items path and gets an HTTP response with the status code 501 (Not Implemented). Try requesting other paths such as /items/42, /itemss/foo, or /foo and compare the response status codes you get.

Routes are the way to expose your business logic endpoints as HTTP endpoints; your Shop service can now be used from the HTTP world!

Building HTTP responses

Actions process HTTP requests and return HTTP responses. So far, you have seen how HTTP requests were routed by the framework to call your application's code. Now, let's see how you can reply with HTTP responses.

An HTTP response has a status code and some optional headers and can be followed by a body. So, to build a response, you have to at least supply a status code.

For instance, your current action definitions return HTTP responses with status code 501 (Not Implemented). Try changing it to Ok (or ok() in Java) and reload the page in your browser (or perform a request with cURL), you should get a response with status code 200 (OK). Play provides helpers to build responses with common status codes. Examples of other predefined statuses are NotFound (notFound() in Java), BadRequest (badRequest() in Java) or InternalServerError (internalServerError() in Java).

More generally, you can build an HTTP response with any status code by using the Status function (or status in Java). For instance, Status(200) (or status(200) in Java) builds an empty response with status 200 and the Content-Length header set to 0.

In addition to a status code, HTTP responses can contain data in a body. For instance, the Application.index action that was provided with the application skeleton returns an HTML document. Alternatively, we can make it return a text document:

val index = Action {
  Ok("Just Play Scala")
}

The equivalent Java code is as follows:

public static Result index() {
  return ok("Just Play Java");
}

In Scala, you can supply a body to your response by calling the apply method of a status; Ok("Just Play Scala") builds an HTTP response with status code 200 and a body that contains "Just Play Scala". Similarly, in Java, you can just pass the response body as a parameter to the status function.

Clients consuming a web service might want (or need) to know the content type of response body data. HTTP responses have a header for this, which is Content-Type. As the value of this header is tied to the type of values you send, Play automatically infers the former from the latter, freeing you from writing redundant code.

In practice, in Scala, writing Ok("foo") builds an HTTP response with a Content-Type header set to text/plain because "foo" has type String. Play infers the right content type by using the type of the value you pass as response body. The type signature of the apply method of the Result type is the following:

def apply[A](a: A)(implicit w: play.api.mvc.Writeable[A]): Result

This means that you can supply a response of type A only if you provide an implicit value of type play.api.mvc.Writeable[A] . The Writeable typeclass actually tells Play which content type to use (and how to serialize it to the HTTP response body). For convenience, Play provides implicit Writeable values for common content types such as JSON, HTML, XML, and plain text. However, if you want to send data of a type that is not currently supported by Play, you have to define the corresponding Writeable instance.

Note

Typeclasses are a feature of the Haskell programming language to achieve ad hoc polymorphism (http://www.haskell.org/tutorial/classes.html). It can be encoded in Scala using parameterized types and implicit parameters.

In Java, the result method helpers, such as ok() and notFound(), are overloaded to support common data types (for example, String, byte[]); ok("foo") builds an HTTP response with a Content-Type header set to text/plain. Data types that are not directly supported must implement the play.mvc.Content interface to be correctly handled by Play. This interface specifies which content type to use and how to serialize the data to the HTTP response body.

Serializing application data in JSON

Now that you know how to build an HTTP response containing a body, your last step to bootstrap your web service consists of returning your business data as a JSON document in the body of your HTTP responses.

Play comes with a rich library for JSON manipulation. Let's start by returning a JSON value in the details action:

import play.api.libs.json.Json

def details(id: Long) = Action {
  shop.get(id) match {
    case Some(item) =>
      Ok(Json.obj(
        "id" -> item.id,
        "name" -> item.name,
        "price" -> item.price
      ))
    case None => NotFound
  }
}

This code tries to retrieve the item in the shop and if found, returns it as a JSON object. The Json.obj function builds a JSON object from a list of name-value pairs. If there is no item with the ID passed as a parameter, the action returns a NotFound response. JSON objects have type JsValue, and Play has a built-in Writeable[JsValue] instance that sets the content type of a JSON response body to application/json.

The equivalent Java code is as follows:

import play.libs.json.Json;

public static Result details(Long id) {
  Item item = shop.get(id);
  if (item != null) {
    return ok(Json.toJson(item));
  } else {
    return notFound();
  }
}

In Java, Play uses the Jackson library (http://jackson.codehaus.org/) to automatically serialize the Item value so that you don't need to explicitly tell how to transform an Item into a JSON object. The Jackson object mapper that performs this task can handle some simple data structures like the Item class, but for more complex data structures (for example, involving cycles or bidirectional associations), you might have to supply your own serialization process by annotating your types with Jackson annotations.

The Scala API does not follow this approach because the Scala language gives convenient mechanisms that allow you to tell how to serialize data without relying on reflection and with minimal boilerplate.

If you call this action from your HTTP client, you will get a response like the following (assuming your shop has an item with the ID 42):

$ curl http://localhost:9000/items/42
{"id":42,"price":4.2,"name":"Play Framework Essentials"}

Similar to the implementation of the details action, here is how you can implement the list action and return the list of the items in the shop as a JSON array. The Java version of the code is as follows:

public static Result list() {
  return ok(Json.toJson(shop.list()));
}

Again, the Json.toJson call delegates the JSON serialization of the list of items to Jackson.

The Scala version of the code is as follows:

val list = Action {
  Ok(Json.arr(shop.list.map(item => Json.obj(
    "id" -> item.id,
    "name" -> item.name,
    "price" -> item.price
  )): _*))
}

We use the Json.arr method to create a JSON array and pass it a collection of JSON objects as a parameter.

You might have noticed that the code defining these JSON objects from the items duplicates the code already written in the details action. Instead, you should isolate the logic corresponding to the serialization of an item into a JSON object as a function and reuse it. Actually, you can do even better; the Play JSON library defines a play.api.libs.json.Writes[A] typeclass that captures the serialization logic for the type A, so you can just write an implicit value of type Writes[Item] and Play will use it when needed. This typeclass has just one method, which is writes(item: Item): JsValue that defines how to transform an Item into a JSON value. The JsValue type is an algebraic data type representing JSON values. For now, you have seen how to define JSON objects (represented by the JsObject type in Play) and arrays (JsArray), using Json.obj and Json.arr, respectively, but there are other types of JsValue such as numbers (JsNumber), strings (JsString), booleans (JsBoolean), and null (JsNull).

Your first reusable JSON serializer for items can be defined and used as follows:

import play.api.libs.json.Writes

implicit val writesItem = Writes[Item] {
  case Item(id, name, price) =>
    Json.obj(
      "id" -> id,
      "name" -> name,
      "price" -> price
    )
}

val list = Action {
  Ok(Json.toJson(shop.list))
}

def details(id: Long) = Action {
  shop.get(id) match {
    case Some(item) => Ok(Json.toJson(item))
    case None => NotFound
  }
}

The implicit value, writesItem, defines the serialization logic for Items. Then, in the list and details actions, we use Json.toJson to transform our items into JSON objects. This toJson method has the following signature:

def toJson[A](a: A)(implicit Writes[A]): JsValue

This means that it can serialize any value of type A if there is an implicit value of type Writes[A] in the implicit scope. Fortunately, Play defines such JSON serializers for common types and can combine them by chaining implicits; this is why Play is able to serialize an Item as well as a List[Item].

Though the code of your writesItem is quite concise, it follows a repetitive pattern. Each field of the Item class is serialized to a JSON field of the same name. Hopefully, Play provides a macro that generates JSON serializers following this pattern, so the previous serializer can be synthesized by just writing the following:

implicit val writesItem = Json.writes[Item]

You might be wondering why automatic generation of JSON serializers is not the default behavior. There are two reasons for this. First, the automatic generation mechanism cannot handle all data types (for example, cyclic data types). Secondly, sometimes you don't want to use the same names for your JSON object fields and your Scala object fields.

Reading JSON requests

Now your web service is able to send JSON data representing the application data. However, clients cannot yet create new data by sending JSON requests; the create action is still not implemented. This action should read the JSON data of requests to extract the information required to create a new item, effectively create the item, and return a response telling the client whether its operation succeeded.

The first step consists in defining which information is required to create a new item:

case class CreateItem(name: String, price: Double)

The equivalent Java code is as follows:

public class CreateItem {
  public String name;
  public Double price;
}

The CreateItem data type just glues together the information needed to create a new item: a name and price. The Java version uses public fields so that it can automatically be handled by the Jackson object mapper.

The CreateItem data type is easy to work with in your server-side code, but it means nothing for HTTP clients that only send JSON blobs. So you also have to define a JSON structure corresponding to the CreateItem data type. A simple solution consists of representing a CreateItem instance with a JSON object by mapping each member of the CreateItem type with a member of the JSON object. That is, a JSON object with a member "name" that contains a string value and a member "price" that contains a number value.

The next step consists of defining how to convert a JSON object consistent with this structure into a CreateItem value.

In Scala, similar to the Writes[A] typeclass that defines how to serialize an A value into a JSON object, there is a Reads[A] typeclass that defines how to get an A value from a JSON object. This typeclass has one abstract method:

def reads(json: JsValue): JsResult[A]

The JsResult[A] type represents either a successful conversion, JsSuccess(a), or a unsuccessful conversion, JsError(errors), which contains a list of errors such as missing fields in the JSON source object. So the Reads[A] typeclass tells how to try to convert a JSON value to an A value.

Play provides Reads[A] values for common types such as String, Int, or Double. You can then combine them to define Reads[A] values for more complex types. For instance, you can define a Reads[CreateItem] value that tells how to try to convert a JSON value to a CreateItem value, as follows:

import play.api.libs.json.{__, Reads}
import play.api.libs.functional.syntax._

implicit val readsCreateItem: Reads[CreateItem] = (
  ((__ \ "name").read[String]) and
  ((__ \ "price").read[Double])
)(CreateItem.apply _)

This code combines the Reads[String] and Reads[Double] values using the and combinator. The (__ \ "name") expression is a JSON path referring to a member "name" so that the (__ \ "name").read[String] expression reads the "name" member as String and the (__ \ "price").read[Double] expression reads the "price" member as Double. Finally, these values are passed to the apply method of the CreateItem data type to make a CreateItem instance. Before showing how to use this JSON reader to effectively transform the content of a JSON HTTP request, let's give more details on the process of transforming JSON blobs to values. As our readsCreateItem type is built by combining two subreaders using and, it tries to apply all of them. If all succeed, the obtained values are passed to the CreateItem.apply function to build a CreateItem instance and the reader returns a JsSuccess[CreateItem] value. If one of the subreaders fails, the reader returns a JsError value.

Tip

The and combinator is not a method of Reads[A]. It is available thanks to an implicit conversion imported by play.api.libs.functional.syntax._. This import brings several other combinators, such as or, which succeeds if one of the two subreaders succeeds. These combinators are not specific to the JSON API, and this is why they are defined in a separate package.

In our case, both sub-readers look up a member in a JSON object, according to a path defined by the \ operator. Note that we can define longer paths by chaining the \ operator. Consider, for instance, the following expression that defines a path locating a member "latitude" nested in a "position" member of a JSON object:

__ \ "position" \ "latitude"

Just like the Writes definition, the readsCreateItem definition is quite mechanical. We try to get each field of the CreateItem case class from a field of the same name in the JSON object. Just like the Writes definition, there is a macro automating the work for Scala case classes so that the preceding Reads definition is completely equivalent to the following:

implicit val readsCreateItem = Json.reads[CreateItem]

In Java, the Jackson mapper is used to convert JSON data to POJOs using reflection, so you don't need to provide similar definitions.

Finally, the last step consists of making the create action interpret request content as JSON data and making a CreateItem value from this data:

val create = Action(parse.json) { implicit request =>
  request.body.validate[CreateItem] match {
    case JsSuccess(createItem, _) =>
      shop.create(createItem.name, createItem.price) match {
        case Some(item) => Ok(Json.toJson(item))
        case None => InternalServerError
      }
    case JsError(errors) =>
      BadRequest
  }
}

The equivalent Java code is as follows:

import play.mvc.BodyParser;

@BodyParser.Of(BodyParser.Json.class)
public static Result create() {
  JsonNode json = request().body().asJson();
  CreateItem createItem;
  try {
    createItem = Json.fromJson(json, CreateItem.class);
  } catch(RuntimeException e) {
    return badRequest();
  }
  Item item = shop.create(createItem.name, createItem.price);
  if (item != null) {
    return ok(Json.toJson(item));
  } else {
    return internalServerError();
  }
}

There are three important points to note in the preceding code. First, we tell the create action to interpret the request body as JSON data by supplying the parse.json value to the Action builder (or in Java, by annotating the method with @BodyParser.Of(BodyParser.Json.class)). In Play, the component responsible for interpreting the body of an HTTP request is named body parser. By default, actions use a tolerant body parser that will be able to parse the request content as JSON, XML, or URL-encoded form or multipart form data, but you can force the use of a specific body parser by supplying it as the first parameter of your action builder (or by using the @BodyParser.Of annotation in Java). The advantage is that within the body of your request, you are guaranteed that the request body (available as the body field on the request value) has the right type. If the request body cannot be parsed by the body parser, Play returns an error response with the status 400 (Bad Request).

Secondly, in the Scala version, the second parameter passed to the Action builder is not a block of the Result type, as with previous actions, but a function of type Request[A] => Result. Actually, actions are essentially functions from HTTP requests (represented by the Request[A] type) to HTTP responses (Result). The previous way to use the Action builder (by just passing it a block of type Result) was just a convenient shorthand for writing an action ignoring its request parameter. The type parameter, A, in Request[A] represents the type of the request body. In our case, because we use the parse.json body parser, we actually have a request of type Request[JsValue]; the request.body expression has type JsValue. The default body parser produces requests of the type Request[AnyContent], whose body can contain JSON or XML content as described previously. In Java, Play sets up a context before calling your action code (just after the routing process) so that within a controller, you can always refer to the current HTTP request by using the request() method.

Thirdly, we make the CreateItem value from this request body by calling request.body.validate[CreateItem] (or Json.fromJson(json, CreateItem.class) in Java). The Scala version returns a JsResult value; this type can either be JsSuccess if the CreateItem object can be created from the JSON data (using the Reads[CreateItem] value available in the implicit scope), or JsError if the process failed. In Java, the result is simply null in the case of an error.

Note

In Scala, there is a body parser that not only parses the request body a JSON blob but also validates it according to a reader definition and returns a 400 (Bad Request) response in the case of a failure so that the previous Scala code is equivalent to the following shorter version:

val create = Action(parse.json[CreateItem]) { implicit request =>
  shop.create(request.body.name, request.body.price) match {
    case Some(item) => Ok(Json.toJson(item))
    case None => InternalServerError
  }
}

Validating JSON data

At this point, your clients can consult the items of the shop and create new items. What happens if one tries to create an item with an empty name or a negative price? Your application should not accept such requests. More precisely, it should reject them with the 400 (Bad Request) error.

To achieve this, you have to perform validation on data submitted by clients. You should implement this validation process in the business layer, but implementing it in the controller layer gives you the advantages of detecting errors earlier and error messages can directly refer to the structure of the submitted JSON data so that they can be more precise for clients.

In Java, the Jackson API provides nothing to check this kind of validation. The recommended way is to validate data after it has been transformed into a POJO. This process is described in Chapter 3, Turning a Web Service into a Web Application. In Scala, adding a validation step in our CreateItem reader requires a few modifications. Indeed, the Reads[A] data type already gives us the opportunity to report errors when the type of coercion process fails. We can also leverage this opportunity to report business validation errors. Incidentally, the Play JSON API provides combinators for common errors (such as minimum and maximum values and length verification) so that we can forbid negative prices and empty item names, as follows:

implicit val readsCreateItem = (
  (__ \ "name").read(Reads.minLength[String](1)) and
  (__ \ "price").read(Reads.min[Double](0))
)(CreateItem.apply _)

The preceding code rejects JSON objects that have an empty name or negative price. You can try it in the REPL:

scala> Json.obj("name" -> "", "price" -> -42).validate[CreateItem]
res1: play.api.libs.json.JsResult[controllers.CreateItem] = JsError(List(
    (/price,List(ValidationError(error.min,WrappedArray(0.0)))), 
    (/name,List(ValidationError(error.minLength,WrappedArray(1))))))

The returned object describes two errors: the first error is related to the price field; it has the "error.min" key and additional data, 0.0. The second error is related to the name field; it has the "error.minLength" key and an additional data, 1.

The Reads.minLength and Reads.min validators are predefined validators but you can define your own validators using the filter method of the Reads object.

Handling optional values and recursive types

Consider the following data type representing an item with an optional description:

case class Item(name: String, price: Double, description: Option[String])

In Scala, optional values are represented with the Option[A] type. In JSON, though you can perfectly represent them in a similar way, optional fields are often modeled using null to represent the absence of a value:

{ "name": "Foo", "price": 42, "description": null }

Alternatively, the absence of a value can also be represented by simply omitting the field itself:

{ "name": "Foo", "price": 42 }

If you choose to represent the absence of value using a field containing null, the corresponding Reads definition is the following:

(__ \ "name").read[String] and
(__ \ "price).read[Double] and
(__ \ "description").read(Reads.optionWithNull[String])

The optionWithNull reads combinator turns a Reads[A] into a Reads[Option[A]] by successfully mapping null to None. Note that if the description field is not present in the read JSON object, the validation fails. If you want to support field omission to represent the absence of value, then you have to use readNullable instead of read:

(__ \ "name").read[String] and
(__ \ "price).read[Double] and
(__ \ "description").readNullable[String]

This is because read requires the field to be present before invoking the corresponding validation. readNullable relaxes this constraint.

Now, consider the following recursive data type representing categories of items. Categories can have subcategories:

case class Category(name: String, subcategories: Seq[Category])

A naive Reads[Category] definition can be the following:

implicit val readsCategory: Reads[Category] = (
  (__ \ "name).read[String] and
  (__ \ "subcategories").read(Reads.seq[Category])
)(Category.apply _)

The seq combinator turns Reads[A] into Reads[Seq[A]]. The preceding code compiles fine; however, at run-time it will fail when reading a JSON object that contains subcategories:

scala> Json.obj(
  "name" -> "foo",
  "subcategories" -> Json.arr(
    Json.obj(
      "name" -> "bar",
      "subcategories" -> Json.arr()
    )
  )
).validate[Category]
java.lang.NullPointerException
        at play.api.libs.json.Json$.fromJson(Json.scala:115)
        …

What happened? Well, the seq[Category] combinatory uses the Reads[Category] instance before it has been fully defined, hence the null value and NullPointerException!

Turning implicit val readsCategory into implicit lazy val readsCategory to avoid the NullPointerException will not solve the heart of the problem; Reads[Category] will still be defined in terms of itself, leading to an infinite loop! Fortunately, this issue can be solved by using lazyRead instead of read:

implicit val readsCategory: Reads[Category] = (
  (__ \ "name).read[String] and
  (__ \ "subcategories").lazyRead(Reads.seq[Category])
)(Category.apply _)

The lazyRead combinator is exactly the same as read, but uses a byname parameter that is not evaluated until needed, thus preventing the infinite recursion in the case of recursive Reads.

Summary

This chapter gave you an idea of the Play framework, but it contained enough material to show you how to turn a basic application into a web service. By following the principles explained in this chapter, you should be able to implement the remaining Items.update and Items.delete actions.

You saw how to generate an empty Play application skeleton using activator. Then, you saw how to define the mapping between HTTP endpoints and your application entry points and the different ways you can bind your controller action parameters from the request URL. You saw how to build HTTP responses and the mechanism used by Play to infer the right response content type. Finally, you saw how to serve JSON responses and how to read and validate JSON requests.

In the next chapter, you will replace the in-memory storage system with a persistent storage system, and you will see how your Play application can be integrated with existing persistence technologies like JDBC.

Left arrow icon Right arrow icon

Description

This book targets Java and Scala developers who already have some experience in web development and who want to master Play framework quickly and efficiently. This book assumes you have a good level of knowledge and understanding of efficient Java and Scala code.

What you will learn

  • Set up a unified development environment for both the clientside and serverside code
  • Understand the challenges of building a scalable web application and master the solutions provided by Play framework
  • Integrate the framework with existing clientside or serverside technologies such as persistence systems
  • Harness the reactive programming model to process data streams
  • Design robust, maintainable, and testable code
  • Be proficient in manipulating JSON data blobs
  • Deploy your application on a PaaS platform
Estimated delivery fee Deliver to South Korea

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Sep 25, 2014
Length: 200 pages
Edition : 1st
Language : English
ISBN-13 : 9781783982400
Vendor :
Apache
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to South Korea

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Publication date : Sep 25, 2014
Length: 200 pages
Edition : 1st
Language : English
ISBN-13 : 9781783982400
Vendor :
Apache
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 87.98
Play Framework essentials
$32.99
Mastering play framework for scala
$54.99
Total $ 87.98 Stars icon
Banner background image

Table of Contents

8 Chapters
1. Building a Web Service Chevron down icon Chevron up icon
2. Persisting Data and Testing Chevron down icon Chevron up icon
3. Turning a Web Service into a Web Application Chevron down icon Chevron up icon
4. Integrating with Client-side Technologies Chevron down icon Chevron up icon
5. Reactively Handling Long-running Requests Chevron down icon Chevron up icon
6. Leveraging the Play Stack – Security, Internationalization, Cache, and the HTTP Client Chevron down icon Chevron up icon
7. Scaling Your Codebase and Deploying Your Application Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.6
(8 Ratings)
5 star 25%
4 star 50%
3 star 0%
2 star 12.5%
1 star 12.5%
Filter icon Filter
Top Reviews

Filter reviews by




Mike Feb 02, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Excellent book with a lot of examples and tips. Provides a continuous learning form the beginning in a medium technical language which helps understanding everything, even if we are new at PLAY.Recomend it for sure. For deep knowledge the Cookbook is also a mandatory book to summarize, review and learn some new tricks.
Amazon Verified review Amazon
Abhishek Srivastava Jun 24, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I love this book. I tried couple of play framework books on safari. I found that either they were were old and examples were obsolete or they were very poorly written.Finally I found this book and it is very recent. all examples work. nothing is obsolete.I also find that the book is comprehensive and well written.
Amazon Verified review Amazon
Martin Nov 24, 2014
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
- Concise reading without long stories.- Short code snippets cover just the important parts of solution.- Includes everything important like session authentication, CSRF prevention and others. (I have not found these topics in few other books.)
Amazon Verified review Amazon
Juraj Zachar Jan 01, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
The content of the book is great but the kindle format is hard to work with. The lack of navigable list of contents makes browsing of the book's chapters cumbersome. I was expecting much better usability and I wish I had gone for a hard cover.
Amazon Verified review Amazon
Dustin Marx Nov 01, 2014
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
"Play Framework Essentials" provides a rapid introduction to the Play Framework. In 7 chapters and under 200 pages, "Play Framework Essentials" introduces Play Framework and covers details such as building and exposing web services with Play, building web application clients that integrate with Play, persisting data from a Play application to a relational database, testing a Play application, refactoring Play application code, and deploying a Play application. The book also describes how developers can take advantage of Play's concurrency model, security support, internationalization support, and caching support."Play Framework Essentials" provides numerous code listings. These are black font on white background with no line numbers and no color syntax. The examples demonstrate applying Play in both Java and Scala programming languages and explains the relatively small number of features that are only available in one language or the other. There are also several graphics in the book that are mostly grayscale but one or two of them has some color in it.Although there are fewer than 200 pages of substantive text in "Play Framework Essentials," the book still manages to cover a significant amount of technical detail. This is accomplished by spending very little time covering historical or background details of the Play Framework and jumping right into technical discussion.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela