Play framework: Add routes from sub-projects dynamically
Asked Answered
F

2

0

I'm developing a system to discover subprojects at compile time. This works. See here. Now the only issue is that the subproject's route file is being ignored.

I know that the normal way to include a route file in the main route file is by hardcoding the latter into the former. But that would defy my goal of dynamic subprojects.

I bet that there's a way to, in Build.scala, discover a route file and append it to the main route file. But I'm a beginner and I have no idea how to do it. Could you please help me out?

Alternatively, if there's no way to do it at compile time, maybe there's a way to load it at runtime? I know there's an api to intercept requests. So if we can read the routes we could implement dynamic routing that way. Is that a good idea?

Ferromanganese answered 29/6, 2015 at 16:6 Comment(0)
F
0

In the end i had to write fragments of the routing file (one per each sub-project, use a different extension like subproject.routes for example) and then concatenate them all together into a single routes file. You have to do this also for the application.conf file.

I did this via the Build.sbt script:

import sbt._
import Keys._
import play._
import java.io._

object Build extends Build {

  val commonSettings: Seq[Setting[_]] = Seq(
    scalaVersion := "2.11.1"
  )

  IO.copyFile(file("conf/base.routes"), file("conf/routes"))

  IO.copyFile(file("conf/base.application.conf"), file("conf/application.conf"))

  lazy val libFolder = file("base-lib");
  lazy val baseLib = processModule(libFolder)

  lazy val modules = (file("modules") * DirectoryFilter).get.map { dir =>
    processModule(dir).dependsOn(baseLib)
  }

  lazy val root = (project in file("."))
    .enablePlugins(PlayJava)
    .settings(
      name := "mainProject",
      version := "1.0"
    )
    .dependsOn(modules map (m => m: ClasspathDependency): _*)
    .aggregate(modules map (m => m: ProjectReference): _*)

  override lazy val projects = root +: modules +: dspcloudLib

  def processModule(dir: File):Project = {
    val p = Project(dir.getName, dir).enablePlugins(PlayJava).settings(commonSettings: _*)

    val mf = new File(dir, "conf/" + dir.getName + ".r")
    val r = IO.read(mf)
    IO.append(file("conf/routes"), r.toString)

    val cf = new File(dir, "conf/" + dir.getName + ".application.conf")
    val c = IO.read(cf)
    IO.append(file("conf/application.conf"), c.toString)

    p
  }
}
Ferromanganese answered 23/10, 2015 at 14:50 Comment(0)
G
0

Your submodules could implement their own routing DSL. See example in api doc. Optionally, you could hook into Compile task in your root project and append all the routes to main routes file programmatically.

Gerger answered 29/6, 2015 at 16:13 Comment(2)
Any example on how to use the Compile task?Ferromanganese
#7821439Gerger
F
0

In the end i had to write fragments of the routing file (one per each sub-project, use a different extension like subproject.routes for example) and then concatenate them all together into a single routes file. You have to do this also for the application.conf file.

I did this via the Build.sbt script:

import sbt._
import Keys._
import play._
import java.io._

object Build extends Build {

  val commonSettings: Seq[Setting[_]] = Seq(
    scalaVersion := "2.11.1"
  )

  IO.copyFile(file("conf/base.routes"), file("conf/routes"))

  IO.copyFile(file("conf/base.application.conf"), file("conf/application.conf"))

  lazy val libFolder = file("base-lib");
  lazy val baseLib = processModule(libFolder)

  lazy val modules = (file("modules") * DirectoryFilter).get.map { dir =>
    processModule(dir).dependsOn(baseLib)
  }

  lazy val root = (project in file("."))
    .enablePlugins(PlayJava)
    .settings(
      name := "mainProject",
      version := "1.0"
    )
    .dependsOn(modules map (m => m: ClasspathDependency): _*)
    .aggregate(modules map (m => m: ProjectReference): _*)

  override lazy val projects = root +: modules +: dspcloudLib

  def processModule(dir: File):Project = {
    val p = Project(dir.getName, dir).enablePlugins(PlayJava).settings(commonSettings: _*)

    val mf = new File(dir, "conf/" + dir.getName + ".r")
    val r = IO.read(mf)
    IO.append(file("conf/routes"), r.toString)

    val cf = new File(dir, "conf/" + dir.getName + ".application.conf")
    val c = IO.read(cf)
    IO.append(file("conf/application.conf"), c.toString)

    p
  }
}
Ferromanganese answered 23/10, 2015 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.