Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring Thymeleaf configuration for reactive support #8124

Closed
danielfernandez opened this issue Jan 27, 2017 · 4 comments
Closed

Refactoring Thymeleaf configuration for reactive support #8124

danielfernandez opened this issue Jan 27, 2017 · 4 comments
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@danielfernandez
Copy link
Contributor

I've been thinking about how Spring Boot could provide autoconfiguration for the new Thymeleaf integration with Spring Web Reactive and, though the view resolver and template engine in themselves present no issues (see my attempt), perhaps the current mechanism for Thymeleaf configuration via the ThymeleafProperties class (which matches spring.thymeleaf.* properties) might benefit from some refactoring.

The issue comes from the fact that the ThymeleafViewResolver (for Spring Web MVC) and the ThymeleafReactiveViewResolver (for Spring Web Reactive) have different needs, so there are properties in the current spring.thymeleaf configuration namespace that wouldn't be used by the reactive side, and vice-versa. But there is still a good amount of properties that would be used in both scenarios, so having some kind of common configuration trunk still looks interesting.

The following properties make sense for both MVC and Reactive (with the same default values):

  • spring.thymeleaf.checkTemplate
  • spring.thymeleaf.checkTemplateLocation
  • spring.thymeleaf.prefix
  • spring.thymeleaf.suffix
  • spring.thymeleaf.mode
  • spring.thymeleaf.cache
  • spring.thymeleaf.templateResolverOrder
  • spring.thymeleaf.viewNames
  • spring.thymeleaf.excludedViewNames
  • spring.thymeleaf.enabled

The following existing properties are actually MVC-only:

  • spring.thymeleaf.encoding
  • spring.thymeleaf.contentType

The following properties would be needed by the Thymeleaf Reactive infrastructure:

  • defaultCharset (type: Charset)
  • supportedMediaTypes (type: List<MediaType>)
  • responseMaxChunkSizeBytes (type: int)

Note how most of the changes in requirements are due to the different way that response content types are managed in the MVC and the Reactive sides. Actually, both the defaultCharset and the supportedMediaTypes properties needed by ThymeleafReactiveViewResolver are in fact inherited from org.springframework.web.reactive.result.view.ViewResolverSupport, so other view resolvers available for the reactive framework might also be affected by this.

The new responseMaxChunkSizeBytes property is only needed for the reactive side because it is meant to be used for specifying the maximum size of the DataBuffer objects generated by Thymeleaf in the Flux<DataBuffer> returned to the server's output channels for template processing.

As for how to refactor this, the first suggestion that comes off the top of my head would be to take the following steps:

  • Keep the ThymeleafProperties class as only source of thymeleaf configuration properties.
  • Deprecate spring.thymeleaf.encoding and spring.thymeleaf.contentType.
  • Create new spring.thymeleaf.servlet.encoding and spring.thymeleaf.servlet.contentType replacing the deprecated ones. Or perhaps .mvc. instead of .servlet., or any other name.
  • Create new spring.thymeleaf.reactive.defaultCharset, spring.thymeleaf.reactive.mediaTypes and spring.thymeleaf.reactive.responseMaxChunkSizeBytes. Not sure about how to handle the multi-valued one though.
  • Simply let the Thymeleaf+MVC autoconfiguration ignore the spring.thymeleaf.reactive.* properties and let the Thymeleaf+Reactive autoconfiguration ignore the spring.thymeleaf.servlet.* ones.

Anyway of course, you know much better the whole set of implications of a refactoring like this, and may be able to find a better approach.

BTW once the new configuration bits are available I'd be happy to contribute the bean autoconfiguration. Or you can just take the code I linked above, adjust it to your taste, and add the new properties.

@philwebb
Copy link
Member

@bclozel I just want to double check if ThymeleafReactiveConfiguration is needed? It looks like it's duplicating ThymeleafDefaultConfiguration.

@bclozel
Copy link
Member

bclozel commented Apr 28, 2017

ThymeleafDefaultConfiguration creates a SpringTemplateEngine for both webapps and non-webapps, as soon as Thymeleaf is available on classpath; indeed, that engine can be used for rendering email templates for a batch application, for example.

ThymeleafReactiveConfiguration provides a SpringWebFluxTemplateEngine, only for reactive web applications. Note that:

  • SpringTemplateEngine implements ISpringTemplateEngine
  • SpringWebFluxTemplateEngine implements ISpringWebFluxTemplateEngine, which extends ISpringTemplateEngine by adding a couple of non-blocking methods (for streaming purposes)

For now, we have no use case for creating a SpringWebFluxTemplateEngine instance for a non reactive webapp (and Daniel argues about that very fact in his PR). Also, the fact that both implementations are based on ISpringTemplateEngine can lead to multiple candidates for injection and quite complex scenario.

@philwebb
Copy link
Member

philwebb commented May 1, 2017

Oh right, they're different types. Ignore me.

@philwebb philwebb closed this as completed May 1, 2017
mbhave pushed a commit to mbhave/spring-boot that referenced this issue May 2, 2017
Thymeleaf 3.0 implements the Spring 5.0 view infrastructure for WebMVC
and the new WebFlux framework. This commit adds auto-configuration for
the WebFlux support.

In that process, the configuration property for `spring.thymeleaf` has
been changed to add `spring.thymeleaf.servlet` and
`spring.thymeleaf.reactive` for MVC/WebFlux specific properties.

Now that the `spring-boot-starter-thymeleaf` does not only support
Spring MVC, the transitive dependency on `spring-boot-starter-web` is
removed from it.

Fixes spring-projectsgh-8124
@danielfernandez
Copy link
Contributor Author

This is awesome, thank you so much. There's just a small thing I think could be improved (related to media types), but I think that should go in a new ticket.

I've now successfully applied auto-configuration based on spring-boot-starter-thymeleaf to Thymeleaf's three current Spring 5 + Spring Boot 2.0 sandbox applications:

Thanks to this new support I've been able to remove almost all bean configuration for Thymeleaf and view resolution (except in one of the apps which actually requires two different ViewResolver instances).

bclozel added a commit that referenced this issue Jul 7, 2017
This commit adds new reference documentation sections about WebFlux
support in Spring Boot:

* Support for multiple HTTP servers (gh-8403)
* `CodecCustomizer` and JSON codecs (gh-8897, gh-9166)
* `WebClient.Builder` auto-configuration (gh-9522)
* Tests with `@WebFluxTest` (gh-8401)
* `WebTestClient` auto-configuration (gh-8399)
* Support for Thymeleafi and Mustache templating (gh-8124, gh-8648)
* Choose another HTTP server with WebFlux (closes gh-9690)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

5 participants