Elegante...
Spiffy é uma estrutura web que usa Scala, Akka (uma implementação de ator Scala) e a API Java Servelet 3.0. Ele faz uso da interface assíncrona e tem como objetivo fornecer um ambiente massivamente paralelo e escalável para aplicações web. Os vários componentes do Spiffy são todos baseados na ideia de que precisam ser módulos minimalistas independentes que realizam pequenas quantidades de trabalho muito rapidamente e transferem a solicitação para o próximo componente no pipeline. Após o último componente terminar de processar a solicitação, ele sinaliza o contêiner do servlet "concluindo" a solicitação e enviando-a de volta ao cliente.
Adicione algumas rotas:
// index page, no code, just text
"""^/$""".r -> "Welcome to Spiffy!",
// main news page
new Regex("""^/(news)/$""") -> NewsController(),
// view some news by id
new Regex("""^/(news)/(view)/(d+)/$""") -> NewsController()
Escreva o controlador:
def receive = {
// handles "news/add/"
case ControllerMsg(List("news", "save"), req, res, ctx) => {
// run validation on the request using Spiffy's validation DSL
var errors:Map[String, Set[String]] = validate (req) (
"email" as email confirmedBy "email_confirm",
"email_confirm" as email,
"title" as (string, 32),
"body" as string,
"tag" as string optional
) match {
case Some(List(errs,warns)) => { // Problem validating
errs
}
case None => None.toMap // passed validation
}
}
// handles "/news/"
case ControllerMsg(List("news"), req, res, ctx) => {
// load up news and stuff in map then render
val params = loadNews
view() ! ViewMsg("news", params, req, res, ctx)
}
// handles "/news/view/$newsId/"
case ControllerMsg(List("news", "view", newsId), req, res, ctx) => {
// usually you want to load the item, in this example we dont
// load item and set the params that the view will render
val news = loadNewsItem(newsId)
val params:Map[Any,Any] = Map("news" -> news)
// ask the view to render
view() ! ViewMsg("newsView", params, req, res, ctx)
}
}
Em seguida, crie alguns modelos. Você pode encontrar mais sobre este exemplo em NewsController e SpiffyConfig
No momento, para usar o Spiffy você deve construir o jar (mvn jar:jar) e adicioná-lo ao classpath da sua aplicação. Você também deve definir a seguinte variável de ambiente (context.xml servirá):
<Environment name="SpiffyConfigObject" value="org.spiffy.config.SpiffyBuiltinConfig" type="java.lang.String"/>
Você precisa substituir org.spiffy.config.SpiffyBuiltinConfig
por um objeto que estenda org.spiffy.config.SpiffyConfig
e forneça todos os valores necessários. Dê uma olhada no SpiffyConfig para ver um exemplo.
Spiffy conta com atores Akka para compartimentar e isolar todos os seus vários componentes. Cada componente do pipeline do Spiffy (exceto o filtro inicial) é composto por um conjunto de atores Akka. Atores sofisticados são apoiados por pools de balanceamento de carga de diferentes tipos de despachantes.
Spiffy é implementado como um filtro. Depois que o filtro recebe a solicitação, ele a coloca em modo assíncrono e a envia ao roteador. O roteador então decide o que fazer com a solicitação inspecionando a URL da solicitação e avaliando-a em relação à sua lista de mapeamentos de controladores conhecidos. Um mapeamento é uma expressão regular que corresponde ao URL solicitado e o atribui ao controlador correspondente. Se uma correspondência bem-sucedida for encontrada, o roteador enviará uma mensagem ao controlador com a solicitação (e todos os objetos necessários que precisam ser enviados junto com ele). Nesse ponto, o trabalho do roteador está concluído e ele fica livre para processar novas solicitações recebidas. Depois que o controlador receber a solicitação, ele executará qualquer lógica necessária na solicitação e poderá decidir encerrar a solicitação ou passá-la para outro componente do Spiffy (geralmente um manipulador de visualização).
Spiffy usa o conceito de ganchos para executar lógica que pode ser encapsulada e executada antes e depois de determinados componentes do pipeline do framework. Os ganchos podem ser executados antes e depois dos controladores e visualizações. Um gancho que será executado antes que um controlador decida ignorá-lo completamente ou pode simplesmente executar alguma lógica, como autenticação ou modificação da própria solicitação, antes que o controlador tenha a chance de trabalhar com ele. Um gancho executado após um controlador também pode redirecionar a solicitação para um controlador diferente, modificá-la ou encerrá-la ali e, em seguida, enviá-la de volta ao cliente. A mesma lógica é usada nas visualizações frontal e posterior, onde o gancho pode interromper a renderização da visualização ou pode passar a saída renderizada para outra parte da estrutura que pode realizar trabalho adicional na saída renderizada.