Ngoc, thanks
1) I think for the future of your framework, adding Scalate back in
would be a very, very good idea. Pretty much everything James Strachan
produces turns to gold (well, Groovy is TBD). Spray, Scalatra,
Circumflex, & Bowler all provide Scalate, and the reason why is clear:
you not only have a clean separation between code/logic and view/
display, you can use, for example, Jade syntax to generate DOM
elements with amazing concision; the same goes for css (via built-in
LESS compiler) and javascript (via CoffeeScript compiler).
Scalate just makes sense, it's type safe and the leanest possible
server-side view implementation around. Major thumbs up for this
component.
2) Automated validation
I love the server-side to client-side validation mirroring, nobody
else is doing this. However, would it not make more sense for
validation to be defined at the (case) class level?
For example:
case class User(age: Int, email: String, name: String, birthDate:
java.util.Date) {
require(age > 99 , t("you're not dead yet?"))
require(isEmail(email), t("please provide a valid email address"))
require(!empty(name), t("name field cannot be blank"))
require(birthDate.isInstanceOf[java.util.Date], t("please select
your birth date"))
def beforeValidate(u: User) {
// for example, convert string birtDate to java.util.Date
prior to create/validate case class
}
}
In this way validation is tied directly to the model (where imo, it
belongs) which makes it impossible to do Person(100,
"invalidemail@.com", "REST API let me through, heh, heh"). I like
this approach, Grails employs it nicely with their ORM, which leads me
to my next point
3) Controller-action files
I'm converting a moderately complex Grails application to Scala. Have
about 40 controllers with @same number of domain/entity classes. Most
of the controllers do basic CRUD, so 4 or more actions per
controller. In Xitrum that either means 160+ controller-action files,
or as you say, embed grouped controller-action classes into a single
file. That could be doable, but not nearly as DRY as one would like.
Outside of the headaches in implementing, what is the problem with
single controller/annotated method approach??
class UserController {
@GET("/user/:id")
def show(id: Long) {
val user = User.find(id)
renderView(user) // by convention Scalate user/show.ext is
called here
}
@GET("/user")
def list() {
List users = User.list()
renderJson(users) // JSON reply to the excellent js DataTables
plugin for example
}
@GET("/user/create")
def create() {
// render form in Scalate WITH validation inferred from case
class and auto-added to jQuery validate
renderView // again, Scalate user/create.ext template called
here by convention
}
@POST("/user")
def save() {
var msg = "user created"
def user = validate(User)
if(!user.errors.get) {
user.save()
}
else msg = "uh oh, problems occurred: " // +
user.errors.toString() not sure how t() deals with runtime
renderView(t(msg))
}
}
I should point out that Xitrum has the most potential to be Rails-
next, which is to say, a blazing fast strongly typed convention-based
web framework. Circumflex guys are working their asses off on other
things; Scalatra just follows Sinatra; Spray guys are all about
stateless REST API for now; Bowler is, I'm not sure what, difficult to
follow it seems. Lift is monolithic, radical context switch to-be-
avoided framework. That leaves Xitrum with a HUGE opening to strike
while the iron is hot ;-)
Oh yes, there is Play, and TypeSafe is backing them so uhhh, the
gorilla is around the corner. I like the complete package that Xitrum
offers more than Play, however. It seems like the Xitrum user base is
small enough at this point for the framework to adapt/evolve.
My vote is clear, bring back Scalate and consider more convention-
based single controller with annotated router methods. I'm sold on
the rest, rocking framework ;-)
Regards,
Noah
On Dec 30, 1:36 pm, ngocdaothanh <
ngocdaoth...@gmail.com> wrote:
> Noah,
> Thanks for the feedback.
>
> 1) Scalate
>
> I'm thinking of adding Scalate back too (early version of Xitrum once
> had it), but since Scala's XML feature is too convenient, I wonder if
> Scala's XML + Scala Enhanced String (
http://jrudolph.github.com/scala-
> enhanced-strings/Overview.scala.html) combination is enough.
>
> 2) Postback
>
> You only need a separate action if you want. Even in that case, Scala
> lets you put multiple classes in one file.
>
> The benefit of the current implementation is you have automatic
> validation for both client side and server side.
>
> With this code:
> {<input type="text" name="username" /> :: MinLength(5) ::
> MaxLength(10)}
> The length is automatically validated on the server side when the data
> is posted back.
>
> I'm thinking of improving/replacing the current implementation with
> Knockout.js + Scala delimited continuation, may be based on Akka
> dataflow (
http://akka.io/docs/akka/1.3-RC5/scala/dataflow.html).
>
> Please try the Todo sample:
https://github.com/ngocdaothanh/xitrum-quickstart/blob/master/src/mai...