Question

My team is looking to re-architect one of our applications in Play2. The application is split up into two web applications that sit on top of the same database: client(read) and admin(read/write).

In the new architecture, we're looking to build two Play2 servers that expose a REST API. There will be two single-page AngularJS apps sitting in front of each. But both servers share common functionality. So we're looking to build a common library which will expose the data access layer (models and DAOs). Each server will have its own set of services.

Client (REST server): read

  • Client-services
  • Common-library

Admin (REST server): read/write (full CRUD)

  • Admin-services
  • Common-library

I'm using IntelliJ 13 and am having a hard time setting this up. I've taken a look at the following sources:

http://www.playframework.com/documentation/2.2.1/SBTSubProjects

http://www.scala-sbt.org/release/docs/Getting-Started/Multi-Project

I believe what I want is add the library type dependency as a (Import Module...), in contrast to adding a module to the parent project

  • myProject

    • app
    • conf
    • public
  • myLibrary

    • src
      • main
        • java
        • scala
  • project
    • Build.scala
Was it helpful?

Solution 2

I solved the problem by abandoning SBT as my dependency/build tool. I ended up using Maven via a plugin (http://nanoko-project.github.io/maven-play2-plugin/maven/release/index.html). The plugin works great. Maven is used as in traditional Java applications.

I created a three pom.xml files for each "project" (Client, Admin, shared library), and an additional pom.xml for parent. Nothing new here. Just your typical Maven setup for multi-project dependencies.

Like I said, the Play2 Maven Plugin works great! I highly recommend it for complicated Play2 applications involving project dependencies.

OTHER TIPS

Since you're using IntelliJ 13, you have access to the built in SBT importing; unfortunately this can't be done on an existing project. You can, however, import a project from an SBT Build file, and then migrate over any project settings from the .idea folder (assuming you're using Directory-based Projects).

With that said, it sounds like you also could use some clarification on setting up the Build.scala, so let's dig into that.

Example Play2 Configuration:

I'm going to go ahead and assume you've already created the two Play projects with play new.

We want to set up the project like this:

  • ClientPlayProject
    • App
    • Conf
    • Public
  • AdminPlayProject
    • App
    • Conf
    • Public
  • SharedLibrary
    • src
      • main
      • test
  • Project
    • Build.scala

Assuming a layout like this, here's an example of what a Build.scala might look like:

import play.Project._
import sbt._
import sbt.Keys._


object BuildSettings {
  val appOrganization = "com.example"

  val appVersion = "0.0.1-SNAPSHOT"

  val commonResolvers = Seq(
    // Your common resolvers here
  )

  val commonSettings = Seq(
    organization := appOrganization,
    // Other shared settings
    resolvers ++= commonResolvers
  )

  val commonDeps = Seq(
    // Shared Dependencies for all 3 projects here.
  )

  val adminDeps = Seq(
    // Admin dependencies
  ) ++ commonDeps


  val clientDeps = Seq(
    // Client Dependencies
  ) ++ commonDeps

  val libraryDeps = Seq(
    // Library Deps
  ) ++ commonDeps
}

object Build extends Build {

  import BuildSettings._

  lazy val LibraryProject = Project("SharedLibrary", file("SharedLibrary"))
    .settings(commonSettings: _*)
    .settings(libraryDependencies ++= libraryDeps)

  lazy val AdminProject = play.Project("AdminPlayProject", appVersion, adminDeps, path = file("AdminPlayProject"))
    .settings(commonSettings: _*)
    .settings(libraryDependencies ++= adminDeps)
    .dependsOn(LibraryProject)

  lazy val ClientProject = play.Project("ClientPlayProject", appVersion, clientDeps, path = file("ClientPlayProject"))
    .settings(commonSettings: _*)
    .dependsOn(LibraryProject)

  lazy val aggregatedProjects = Seq[ProjectReference](
    LibraryProject,
    AdminProject,
    ClientProject
  )

  lazy val root = Project("Root", file("."))
    .settings(commonSettings: _*)
    .aggregate(aggregatedProjects: _*)
}

As soon as you've got your Build.scala all squared away, just do the Import Project step in IntelliJ and it'll get your code completion all squared away and good to go.

As a note, you may want to break parts of this up into other .scala files and import them; perhaps a Dependencies object, a Resolvers object, etc. It really depends on the complexity level.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top