scalatra
scalatra copied to clipboard
Separating CoreDsl from ScalatraBase
Would it be possible to separate CoreDsl
from the ScalatraBase
? This would make it possible to define own typesasfe DSL for the HTTP verbs? (Something like def get(transformers: RouteTransformer*)(block: => MyTypesafeResult): Route
)
Why, you ask?
We're refactoring from json4s
to argonaut
, and like to make it impossible to call e.g. the following:
import JsonImplicits.FooCodecJson
get("/foo") {
// This compiles but won't produce JSON at runtime,
// because argonaut cannot do that dynamically (no reflection).
// Block argument of type `=> Any` is dangerous... :(
Foo("bar", 5)
}
I am afraid that modifying the DSL (e.g. change the signatures or move the methods out from ScalatraBase
) is not possible without breaking existing code. I see three options:
- Restrict the return type on your own (see below)
- Create an opt-in solution on which new applications can build for Scalatra 2.x and existing code still runs without modifications.
- Think how to do this in a Scalatra 3.x, possibly built on http4s.org
You also might want to take a look at https://github.com/ceedubs/scrutinator and https://github.com/ceedubs/scrutinator-pet-store.
import org.scalatra.{ScalatraServlet, ActionResult, Ok}
case class Foo()
case class Bar()
type ResponseRenderer[A] = A => ActionResult
object Renderers {
def responseRenderer[A](x: ResponseRenderer[A]) = x
implicit val fooRenderer = responseRenderer[Foo](x => Ok("foo"))
def restrictTo[A:ResponseRenderer](x: => A): A = x
}
import Renderers._
trait FooServlet extends ScalatraServlet {
get("/api/foos")(restrictTo[Foo] {
Foo()
})
// does not compile
get("/api/bars")(restrictTo[Bar] {
Bar()
})
}
@dozed @seratch Should we move this issue to 2.6.0 or 3.0.0 milestone?
Removed from the milestone once to close 2.5.0 milestone which has been already released. If we should add this to the future plan, set the milestone again, please.