In this tutorial we will create a new Play Framework application from scratch and play around with its build. We will see how to work with config, use compile-time dependency injection, how to dock...
Prerequisites
Download and install JDK 8+ from AdoptOpenJDK’s website. Use HotSpot JVM (default). Download and install Docker. Download and install SBT and Scala, e.g using Homebrew o...
Creating a skeleton project
Generate a skeleton with giter8 In terminal, in your repos directory, create a new project using a giter8 template for play-scala-seed: 1 2 cd ~/repos sbt new playframework/play-scala-seed.g8 Yo...
Creating a git repository
We will create a git repository to host our code. Prepare .gitignore file We will create a .gitignore file that contains files that should not be tracked. gitignore.io creates a .gitignore file a...
Open the project in IntelliJ
Open the project In IntelliJ, click File -> Open, navigate to the project directory (playground) and click open. TIP: tick v under: Library sources sbt sources use sbt shell...
Create a package
Create a package Let’s create a binary version of our application. Open the sbt shell and type dist. This task will create a new zip in your project directory under target/universal/ directory. Th...
Dockerize the app
Instead of creating a binary package as our artifact, we will create a docker image. Docker use operating-system-level virtualization to deliver software in packages called containers. You can run...
Working With Config
We will first start by adding demo config to our app and reading it manually. Add the following to your conf/application.conf (not inside, but rather under play’s blob): 1 2 3 4 5 6 7 8 9 10 11 12...
Class-up Your Config
In the previous example there was some repetition. Parsing the config to a person was a bit complex, as well as creating a Path instance, UUID instance and so on. A bigger problem is that it is no...
Compile-Time Dependency Injection
When you add a dependency to a controller (directly or indirectly) or when you refactor a class - if you forget to wire a dependency in your module, you will encounter this error at runtime. We wou...
Adding Logic
We will add some logic and refactor in the next sections. We will build a dish menu for our users. Defining Routes First, let’s add three new routes to the conf/routes file: 1 2 3 GET /dishes...
Moving the logic to a library
Even though the marshalling and unmarshalling of the request is much simpler now, our logic is still written in the controller. This means that in order to test our logic we need to create an appli...
Adding database access
We will read the dishes from a DB instead of from a mutable set in memory. Add JDBC and DB driver Add jdbc support and h2 driver to your project. in build.sbt: 1 2 3 4 5 libraryDependencies ++= ...
DB evolutions
You can create your schema manually and the app will work. However, each developer that clones the code will have to do so too, and it results in a poor development experience. While we have many r...
Play modes
Play has 3 modes: Dev, Prod and Test. Whenever a play application is started, it is started using one of the 3 modes above. For example, when running Play with sbt run the mode will be Dev. When r...
Circe
play-json enabled us to class-up json (deserializing it from string to a case class) and to serialize json with relative ease. Circe (pronounced SUR-see) is yet another JSON library for Scala. It ...
Macwire
How MacWire works MacWire uses scala macros to instantiate new objects, using values in the enclosing types for constructor parameters. Consider 2 services, X and Y, and three dependencies, A, B ...
SLF4J
It’s time to add logging to our app. We will add logging using SLF4J, and bind the implementation to logback. SLF4J, Simple Logging Facade for Java, serves as a simple facade or abstraction for va...
Scalafmt
Scalafmt formats code so that it looks consistent between people on your team. For example, it can automatically rewrite this code, which has a weird indentation: 1 2 3 4 5 // Example 1: parameter...