Mustache Integration with HTTP Routing¶
Mustache support for HTTP servers is provided by the finatra/http-mustache library. This integrates Finatra’s general Mustache support with Finatra’s HTTP MessageBodyComponents.
You must include the c.t.finatra.http.modules.MustacheModule in your server’s list of modules in order for the framework to negotiate rendering of Mustache templates via MessageBodyComponents.
import com.google.inject.Module
import com.twitter.finatra.http.modules.MustacheModule
import com.twitter.finatra.http.HttpServer
class MyServer extends HttpServer {
override val modules: Seq[Module] = Seq(MustacheModule)
???
}
The c.t.finatra.http.modules.MustacheModule includes the general MustacheFactoryModule which is explained in the general Mustache support documentation here.
Responses¶
As a callback return type¶
To generate an HTTP response rendered from a Mustache template you can simply
return a @Mustache
-annotated object or a MustacheBodyComponent as the result of your route callback.
The framework will use Mustache to render callback return types that
are annotated with the @Mustache
annotation or are an instance of a MustacheBodyComponent. E.g.,
@Mustache("foo")
case class FooView(
name: String)
get("/foo") { request: Request =>
FooView("abc")
}
The value of the @Mustache
annotation is assumed by the c.t.finatra.mustache.writer.MustacheMessageBodyWriter to be the template
filename without the suffix (which the framework always assumes to be .mustache).
Thus in the example above, this attempts to locate the foo.mustache template and uses the fields of the FooView to populate the template then returns the result as the body of an 200 - OK response.
Explicitly created response body¶
Or you can manually create a response via the c.t.finatra.http.response.ResponseBuilder which explicitly references a template, e.g.,
import com.twitter.finatra.http.marshalling.response._
get("/foo") { request: Request =>
...
response.notFound.view(
template = "notFound.mustache",
obj = NotFound("abc"))
}
Note
The #view methods are implicits added to the c.t.finatra.http.response.EnrichedResponse by importing the implicit RichEnrichedResponse into scope with import com.twitter.finatra.http.marshalling.response._.
As part of a response body¶
Or you can programmatically render a template into a string using the c.t.finatra.mustache.marshalling.MustacheService#createString method. This is useful for embedding the resultant content inside a field in a response.
import com.twitter.finatra.mustache.marshalling.MustacheService
case class TestUserView(
age: Int,
name: String,
friends: Seq[String])
case class TestCaseClassWithHtml(
address: String,
phone: String,
renderedHtml: String)
get("/testClassWithHtml") { r: Request =>
val testUser = TestUserView(
28,
"Bob Smith",
Seq("user1", "user2"))
TestCaseClassWithHtml(
address = "123 Main St. Anywhere, CA US 90210",
phone = "+12221234567",
renderedHtml = xml.Utility.escape(mustacheService.createString("testHtml.mustache", testUser)))
}
The MustacheService is part of the framework’s generic Mustache support. For more information see the Finatra Mustache section.
Template Resolving¶
To better understand how Mustache templates are resolved via the
@Mustache
annotation or from a c.t.finatra.http.marshalling.MessageBodyComponent, please see MustacheTemplateLookup and the
corresponding MustacheTemplateLookupTest.
For more information on referencing files in Finatra, see the Working with Files section.