Trimness aims to be an extensible tool to build a lightweight service for rendering templates (e.g. a simple reporting application). It's built on several open source projects. The fundamental ones are Trimou (mustache/handlebars-like templating engine), Weld (component model, extensibility) and Vert.x (web server, routing, event bus).
<dependency>
<groupId>org.trimou</groupId>
<artifactId>trimness-core</artifactId>
<version>${version.trimness}</version>
</dependency>
The best place to start is probably the simple example. Clone the repository, build the project and run the example shaded jar:
$ git clone git@github.com:trimou/trimness.git
$ mvn clean install
$ java -jar examples/simple/target/trimness-example-simple-shaded.jar
A simple UI with test form is located at localhost:8080/test
.
Insert commits-list.html
in template id field and hit render button.
You should get a link to a result - HTML page with list of last commits from this repository.
Trimness's business is to render templates. There are two ways to send a "render request".
- HTTP endpoints
- Vert.x event bus
HTTP method | Path | Consumes | Description |
---|---|---|---|
POST | /render | application/json | Send sync/async render request |
GET | /result/{resultId} | - | Get the result of a render request |
DELETE | /result/{resultId} | - | Remove the result of a render request |
GET | /result/link/{linkId} | - | Get the result for the specified link |
GET | /monitor/health | - | Simple health-check resource |
GET | /template/{id} | - | Attempt to find the template with the given id |
Let's use curl
to perform a very simple render request:
curl -X POST -H "Content-Type: application/json" -d '{ "templateContent" : "Hello {{model.name}}!", "model" : { "name" : "Foo"} }' http://localhost:8080/render
The reply should be Hello Foo!
.
Let's analyze the request payload.
content
property is used to specify the template for one-off rendering (TIP: it's much better to leverage the template providers and template cache - see below).
model
property holds the data used during rendering (TIP: model is not the only source of data - see model providers below).
By default, the request is synchronous which means that the client is waiting for the rendered output. If we change the payload to:
{ "templateContent" : "Hello {{model.name}}!", "model" : { "name" : "Foo"}, "async": true }
Then trimness replies immediately with something like:
{ "time" : "2017-05-19T11:25:50.393", "resultId" : "1495185748798", "timeout" : "2017-05-19T11:30:50.393"}
time
is the current server time.
timeout
is the time after which the result might be removed automatically (it depends on the underlying result repository implementation).
The resultId
is used to pick up the result later:
curl http://localhost:8080/result/1495185748798
And the reply should be again Hello Foo!
.
Sometimes it might be useful to specify a more memorable link that could be used instead of the result id:
{ "templateContent" : "Hello {{model.name}}!", "model" : { "name" : "Foo"}, "async": true, "linkId" : "foo-1" }
linkId
is used to specify a link that could be also used to get the result:
curl http://localhost:8080/result/link/foo-1
We can also specify the result type:
curl http://localhost:8080/result/1495185748798?resultType=metadata
In this case, the reply would be:
{ "time" : "2017-05-19T11:25:50.393", "result" : { "id" : "1495185748798", "templateId" : "oneoff_1495201157642", "output" : "Hello Foo!", "status" : "SUCCESS" }}
Vert.x message consumers are automatically registered for addresses listed below. The message/reply payload is always JSON and follows the contract used for HTTP endpoints (where possible).
Address | Description |
---|---|
org.trimou.trimness.render |
Sync/async render request |
org.trimou.trimness.result |
Get the result of a render request |
org.trimou.trimness.result.remove |
Remove the result of a render request |
org.trimou.trimness.result.link |
Get the result for the specified link |
The template provider is responsible for looking up and loading contents of the templates.
There might be several template providers installed.
Providers with higher priority are queried first.
There are two built-in template providers available.
FileSystemTemplateProvider
which loads templates from the local filesystem.
And ClassPathTemplateProvider
which loads templates from the class path.
Provides data models for templates.
The model can be used in templates - the result set via ModelRequest#complete(Object)
is accessible under the namespace key (defined by getNamespace()
).
If a model request is not processed within TrimnessKey#MODEL_INIT_TIMEOUT
the potential result is ignored afterwards.
A simple example is the GithubModelProvider.
This model provider fetches info about repository commits using api.github.com
which is later used in the template.
There is one built-in model provider - GlobalJsonModelProvider
which attempts to read a JSON file from the class path or the filesystem and if it exists and can be read, then provide all the data found to all templates.
This component is used to store the results of render requests.
A valid repository with the highest priority is used.
By default, InMemoryResultRepository
is used.
If org.trimou.trimness.resultDir
property is set and represents a valid directory path then FileSystemResultRepository
is used instead.
This repository is slower but results survive application restart.
Trimness can be configured through system properties, environment variables and trimness.properties
file.
The built-in options are listed in an enum: https://github.com/trimou/trimness/blob/master/core/src/main/java/org/trimou/trimness/config/TrimnessKey.java.
Trimness is not meant to be deployed to a container (such as Java EE).
Instead, add trimness-core.jar
and its dependencies to the class path of your application or use maven-shade-plugin
to build a fat jar, see for example: https://github.com/trimou/trimness/blob/master/examples/simple/pom.xml#L25.