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 [email protected]:trimou/trimness.git
$ mvn clean install
$ java -jar examples/simple/target/trimness-example-simple-shaded.jarA 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/renderThe 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/1495185748798And 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-1We can also specify the result type:
curl http://localhost:8080/result/1495185748798?resultType=metadataIn 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.