Search code examples
spring-bootkotlinmustache

How does a SpringBoot controller know to return a mustache template instead of a String


I'm walking through a tutorial on Spring Boot using Kotlin. I'm new to Kotlin and Spring, though I've already worked in a couple of different MVC style frameworks in other languages so get the gist.

Something that I don't get as I work through this tutorial is how in these controller methods:

package com.example.blog

import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping

@Controller
class HtmlController(private val repository: ArticleRepository) {

    @GetMapping("/")
    fun blog(model: Model): String {
        model["title"] = "Blog"
        model["articles"] = repository.findAllByOrderByAddedAtDesc().map {
            it.render()
        }
        return "blog"
    }
}

Where we see return "blog" at the end Spring knows to return a mustache template with the provided model.

I would have expected something like return MustacheView("blog", model)(I know that's not a real class or method, just psudocoding to exemplify) or something like that where you're explicitly saying "hey return this as a mustache template and not just the string blog"..

I'm sure there's some magic behind the scenes where spring says "oh hey, you have the mustache dependency installed, when you return this string from a controller you must be referring to a template name", but I can't see in the documentation where that's spelled out.

It's not completely necessary to know to finish the tutorial, but it feels like a bit of unexplained magic at the moment and I'd like to know what's going on.


Solution

  • When you return a String, it is used as a view name. This view name is then resolved into a View implementation.

    In the case of Mustache, Spring Boot auto-configures a MustacheViewResolver bean. This bean is then picked up by Spring MVC and used to turn your "blog" into a MustacheView backed by your Mustache template. It is then combined with the Model that was passed into your controller method and rendered.