Play framework is a MVC style web application framework for JVM built using Scala, Akka, and Netty. It provides API for both Java and Scala programming languages. You can use it to build either your traditional web applications with server side rendering or modern single-page application (SPA) that uses REST with JavaScript MVC framework like AngularJS. One design decision that makes Play different from other Java/Scala MVC web frameworks is that it is not built on top of the Servlet standard. It is full stack Java framework that runs your application stand-alone. Play is a framework not a library.
In this tutorial series, we will build a blogging platform called blogy that you can use to write and publish blogs.
To work along with this tutorial, you will need following installed on your machine.
-
Download and install latest JDK 8 update on your operating system. I am using JDK version
1.8.0_60. -
Download and install latest Scala version on your machine. I am using Scala
2.12.3. -
Download and install the latest SBT version on your machine. I am using SBT version
0.13.16. -
An IDE of your choice. You can use either of IntelliJ or Eclipse. I prefer IntelliJ.
-
You should be comfortable reading and writing Scala code. Throughout the tutorial series, we will also use SBT so in case you are not familiar with SBT then you can read my SBT tutorial.
The code for demo application is available on github: blogy. You should get the part-01 release. If you are not comfortable with Git, then you can directly download the part-01.zip.
Okay, let's get started with application development.
In this series, we will use the latest Play framework version 2.6.3. Play documentation recommends that one should download a Starter Project to quickly get started with Play framework. These starter projects contains everything you need to go from zero to a running Play project. There are a lot of official and templates that one can choose from. You can also start a new project using sbt new like:
$ sbt new playframework/play-scala-seed.g8For Scala projects or:
$ sbt new playframework/play-java-seed.g8For Java based projects.
Both templates above generate minimum projects so that you can get (almost) only the basic project structure. But you can also create the project manually if you think it is less intimidating and easier to understand.
Open a new command-line terminal and navigate to a convenient location on your file system where you want to host the application source code. Let's call the application folder blogy.
$ mkdir -p blogy/{app/controllers,conf,project}
$ cd blogyCreate the following directory layout:
blogy/
├── app
│ └── controllers
├── conf
└── project
We will start with creating our build file build.sbt. Play uses SBT to build and run the application. Create a new file build.sbt inside the root i.e. blogy directory and populate it with following contents.
name := "blogy"
version := "1.0.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.3"
libraryDependencies += guiceThe build file shown above does the following:
- It specified name of the project as
blogy. - Then, we specified version of the project as
1.0.0-SNAPSHOT. - Next, it enables
PlayScalaplugin forblogyproject. Later, we will add Play SBT plugin to theblogyapplication. - Finally, we set Scala version to
2.12.3.
Now, we will add Play Scala plugin to our project so that it is treated as a Play application. In SBT, you declare plugins you need in your project by adding them to plugins.sbt file inside the project directory. Create a new file plugins.sbt inside the project directory and populate it with following contents.
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.3")This is one required SBT plugin that we will need in our project. There are many more plugins like sbt-coffeescript, sbt-less, sbt-scalariform, etc that we can add for adding different capabilities to our project. We will add few more plugins later in this series.
It is a good practice in SBT projects to lock down the version of SBT. By default, the installed version of SBT will be used by the application. This might cause compatibility issues if the future version of SBT becomes incompatible with Play. To force a SBT version, create a new file build.properties inside the project directory and add the following line to it.
sbt.version=0.13.16
Now, to test our current setup launch the sbt command from inside the blogy directory. You will see output as shown below.
$ sbt[info] Loading global plugins from /Users/shekhargulati/.sbt/0.13/plugins
[info] Loading project definition from /Users/shekhargulati/dev/git/play-the-missing-tutorial/blogy/project
[info] Updating {file:/Users/shekhargulati/dev/git/play-the-missing-tutorial/blogy/project/}blogy-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to blogy (in build file:/Users/shekhargulati/dev/git/play-the-missing-tutorial/blogy/)
[blogy] $
Write play and press tab you will see all play specific tasks.
[blogy] $ play
playAggregateReverseRoutes playAllAssets playAssetsClassloader playAssetsWithCompilation playCommonClassloader playCompileEverything playDefaultAddress
playDefaultPort playDependencyClasspath playDevSettings playDocsJar playDocsModule playDocsName playExternalizeResources
playExternalizedResources playGenerateReverseRouter playGenerateSecret playInteractionMode playJarSansExternalized playMonitoredFiles playNamespaceReverseRouter
playOmnidoc playPackageAssets playPlugin playPrefixAndAssets playReload playReloaderClasspath playRoutes
playRoutesGenerator playRoutesImports playRoutesTasks playRunHooks playStop playUpdateSecret
To run a Play project, you can use the run task. It will start the server at port 9000.
[blogy] $ run
--- (Running the application, auto-reloading is enabled) ---
[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
(Server started, use Enter to stop and go back to the console...)
You can specify a different port number by just passing it along with run task like
run 8080. This will start Play application at port 8080.
You can access the application at http://localhost:9000/. On accessing the page, you will be greeted with following error message.
java.io.IOException: resource not found on classpath: application.conf, application.json
Every play framework application needs a configuration file application.conf inside the configuration directory. Create a new file application.conf. You can have an empty configuration for now and then the defaults will be used. application.conf uses HOCON(Human Optimized Config Object Notation) notation. According to HOCON documentation,
The primary goal is: keep the semantics (tree structure; set of types; encoding/escaping) from JSON, but make it more convenient as a human-editable config file format.
Access the index page http://localhost:9000/ again, this time you will be greeted by different error page.
The reason for this error message is that we have not mapped any action to the GET request to index / path.
You now have a working Play application environment. Let's write our first Play controller. In Play, you write controllers which define Actions that process the request and return response. The decision to select an Action is made by the router which uses the routes configuration to select the correct Action. The router looks at the request details like method, path and query parameters to decide which Action should handle the request.
Create your first controller inside the app/controllers directory. We will name our controller IndexController as it is handling the index request.
package controllers
import javax.inject._
import play.api.mvc._
class IndexController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
def index() = Action {
Ok("Hello, World!")
}
}The code shown above does the following:
- It import all the classes and traits inside the
javax.injectandplay.api.mvcpackages. - Next, we created a Scala class that extends
BaseControllertrait.BaseControllerprovides access to all the utility methods to generateActionandResulttypes and requires that you implementscontrollerComponentsmethod. - So we inject an instance of
ControllerComponentsas avalto have a full implementation ofBaseController.s - Finally, we created a method
indexthat returns anAction. Action is a functionRequest[A] => Resultthat takes a request and returns a result. We returned HTTP status Ok i.e. 200 withHello, World!text in the response body. Action syntaxAction {}is possible because of aapplymethod defined in theActionobject that takes a blockdef apply(block: => Result): Action[AnyContent].
Now, we will map the index URL / to index Action by defining configuration in the routes configuration. Create a new file routes inside the conf directory.
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
GET / controllers.IndexController.index()
As is obvious, we are mapping HTTP GET request to / to controllers.IndexController.index() action method.
You can now test that / url is working by either opening http://localhost:9000/ in the browser or using a command-line tool like cURL as shown below.
$ curl -i http://localhost:9000/HTTP/1.1 200 OK
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'
X-Permitted-Cross-Domain-Policies: master-only
Date: Fri, 08 Sep 2017 22:33:29 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 12
Hello, World
You can map multiple URLs to the same action by defining the route configuration for new URL. Let's suppose we want to map both / and /index to the same controller then we can update our routes file as shown below.
GET / controllers.IndexController.index()
GET /index controllers.IndexController.index()
Every Play application has access to the Play documentation at http://localhost:9000/@documentation/Home.
When you run the Play application using the
runtask, Play application is launched in thedevmode. In dev mode, sources are constantly watches for changes, and whenever source changes project is reloaded with new changes. There are two other modes of Play application -testandproduction. We will look at them later in this series.
You can stop the running server by pressing Ctrl+D Or ENTER. This will take you back to the SBT shell. If you will press Ctrl+C then SBT process will also exit and you will be back to your command-line terminal.
That's it for the first part of Play framework tutorial. If you have any feedback then you can add a comment to this Github issue #1.
You can read next part here.
