Angular 8 with Play Framework 2.7.x

Yohan Gomez
7 min readDec 5, 2017

--

TL;DR: Use play framework to develop the application backend/services and frontend using Angular CLI, all in a totally integrated workflow and single unified console. This approach will deliver perfect development experience without CORS hassle. Fork or clone the seed project of your language preference and get started:

Java Seed: https://github.com/yohangz/java-play-angular-seed
Scala Seed: https://github.com/yohangz/scala-play-angular-seed

Are you looking for React? React with Play Framework 2.7.x

Are you building a web application with Angular? Angular is super cool! We all know that. But are you looking for a good backend framework to pair with it? No clue on how to get started without going through the pain of setting up things from scratch. Doesn’t matter whether you are building a production ready application or a proof of concept project, You are at the correct place, let’s dive into detail.

What the heck is play framework?

Play is a high-productivity Java and Scala web application framework that integrates the components and APIs you need for modern web application development.

Play is based on a lightweight, stateless, web-friendly architecture and features predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications thanks to its reactive model, based on Akka Streams.
Refer: https://www.playframework.com/

When I was introduced to play framework, I was a little skeptical to move ahead and adopt the new shiny thing wondering whether it has support? Prod ready? Does it have all what they say it does? Trust me, it does have all those things as they claim, and it’s extremely fast and so damn easy to learn. You can use either java or scala to write an application with play framework.

Let’s not talk about how play framework works in this article, it’s a topic for another article. Go through their site, it has all that you are looking for

Why Play Framework with Angular? Scala views are already available out of the box with play ;)

But wait! It’s a full fledged mvc framework with view support! Booo… Read the topic pal, we want to build the frontend with Angular. So lets say goodbye to scala views, which comes out of the box with play framework.

Then what is the architecture of this project? We are simply going to use play framework backend/services along with Angular frontend served through play routes.

This sounds complicated, aren’t it? Nahhh! It’s a piece of cake. You’ll realize how easy it is in a bit!

What are the approaches available to combine Play backend with Angular

1| Build backend and frontend isolated in different projects and use REST interface to communicate.

Pros:

  • Frontend and backend concerns are separated out to different projects.
  • Frontend can be deployed in a CDN.

Cons:

  • Isolated deployment steps are required for both backend and frontend.
  • Need to enable CORS to directly access services exposed from other origins or same origin different ports.
  • All the API’s are exposed to the external parties with cross origin accessibility.
  • Development experience is bad (one command run project is not available).

2| Build both backend and frontend in the same project: Use scala views to expose frontend entry point and communicate with backend using the REST interface.

Pros:

  • Play activator associated commands (run, build, publish, etc..) to triggers frontend tasks associated (no need to worry how things get wired up).
  • No more CORS hassle, secure out of the box.
  • Easy CI/CD integration.

Cons:

  • Have to manage frontend code in multiple places (index html within scala views and rest of the code in frontend sub directory).
  • Development time experience is bad (Hard to get watch task working properly).
  • AoT build and other optimization implementation is hard.
  • No clear separation between frontend and backend code.
  • Frontend cannot be deployed in a CDN directly (It is technically feasible using a reverse proxy).

3| Build both frontend and backend in the same project: Use play static routes to serve frontend and communicate with backend using the REST interface. This is the approach that we are using.

Pros:

  • Play activator associated commands (run, build, publish, etc..) to triggers frontend tasks associated (no need to worry how things get wired up).
  • Painless development experience (with play run hooks). Watch task with live reload and what not.
  • No more CORS hassle, secure out of the box.
  • Clear separation between frontend and backend code.
  • Frontend code is served via the same server instance which is serving the backend.
  • Easy CI/CD integration.

Cons:

  • Need to write proxy API’s to access micro services to ensure security (which is not a bad thing anyway).
  • Frontend cannot be deployed in a CDN directly (It is technically feasible using a reverse proxy).

Shall we get started?

We have built a working seed project for you, You don’t have to go through the pain of understanding the whole thing on your own (if you are lazy like me). There are couple of seed projects available, chose depending on your language preference.

Java Seed: https://github.com/yohangz/java-play-angular-seed
Scala Seed: https://github.com/yohangz/scala-play-angular-seed

If you are the guy who wants to know all the minor details and do it on your own, let’s dive in:

Base Structure

  • Generate a play project via activator or download starter project via play framework official site.
  • Clean all the contents within public directory, remove all default controllers view and services, etc..
  • Create a /ui directory within root directory of the project.

Frontend Codebase

  • Use Angular CLI to generate the frontend code base within /ui directory.
  • Modify the /ui/package.json file within Angular code base. Introduce following npm scripts: (You can customize either of these tasks depending on your requirements)

1| Start command use proxy config which is explained later.
2| Both build-dev and build-prod command output directories has been changed to public directory within play project root. Later these files will be served via play static routes.
3| Prod-build use AoT

Backend Codebase

  • Include FrontendCommands.scala file under /project directory. Why? This object contains all the frontend build associated commands. Change the task names accordingly if you wish to change them in /ui/package.json file or change the package manager to yarn.
  • Include FrontendBuild.scala file under /project directory. Why? This is a play run hook implementation to trigger frontend associated watch (serve or start) task command on play activator run.

Note: additionally this will install node modules required for frontend on initial run if node modules are not installed.
Ref: https://www.playframework.com/documentation/2.7.x/SBTCookbook

  • Introduce ui-build.sbt file under project root directory. This file contain the play sbt task mapping to frontend build tasks associated and bind the previously created play run hook.
  • Include FrontendController.scala under controllers directory. This file contains the asset controller wrapper serving frontend assets and artifacts. Additionally include apiPrefix configuration key in application.confwhich is referred by this controller.
  • Include following routes in route file under conf. Note: Use the exact order of routes.
  • Expose all backend associated routes via play codebase which can be consumed in frontend directly.

Final directory structure

… and we are done ;)

Other solutions out there

Even though there are other solutions, those might not be comprehensive as ours but you decide it for yourself. ;)

Conclusion

Fork or clone the seed projects and get started

Java Seed: https://github.com/yohangz/java-play-angular-seed
Scala Seed: https://github.com/yohangz/scala-play-angular-seed

Who made this happen

Credits

Thanks for the support guys and awesome!

References

📝 Read this story later in Journal.

🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >

--

--