title: Spring Boot resource handler patterns for single page applications
body: <p>I have the following in my Spring Boot configuration:</p>
  
  <pre><code>@Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.setOrder(Ordered.HIGHEST_PRECEDENCE)
              .addResourceHandler("**/*.*")
              .addResourceLocations("file:static/");
  }
  </code></pre>
  
  <p>Since I'm creating a single page app I want this resource handler to deliver static files if the following is true:</p>
  
  <ul>
  <li>URL does not start with <em>/api</em></li>
  <li>This resource handler contains a file that matches the path from the URL</li>
  </ul>
  
  <p>If there are no matching file, the resource handler <strong>should not respond with 404</strong> but let the call through to the controllers of the project.</p>
  
  <p>In one of them I place my fallback to index.html annotation (again unless the URL starts with /api):</p>
  
  <pre><code>@GetMapping({"/**", "/"})
  </code></pre>
  
  <p>This last part works fine but the problem is that the resource handler returns a 404 if there are no matching files instead of letting the call through (I'm used to the middleware patterns of Node.js and Go) to the controllers. How can I achieve this? Can I create my own resource handler that acts more middleware like?</p>
  
  <p>In Go with Echo for example you just need to enable HTML5 with a skipper function for /api:</p>
  
  <pre><code>func main() {
      server := echo.New()
  
      server.Use(middleware.Static("static"))
      server.Use(middleware.StaticWithConfig(middleware.StaticConfig{
          Root:    "static",
          HTML5:   true,
          Skipper: noHTML5IfAPICallSkipper,
      }))
  
      server.Logger.Fatal(server.Start(":1323"))
  }
  
  func noHTML5IfAPICallSkipper(context echo.Context) bool {
      if strings.HasPrefix(context.Path(), "/api/") {
          return true
      }
  
      return false
  }
  </code></pre>
  
  <p>How to enable this single page app routing patterns in Spring Boot?</p>
  
  <p>Oh, and by the way, it's crucial that the static files are served from disk rather than from a classpath or anything else that is packaged inside a jar. This service will run with Docker and it has to be possible to mount the files from outside the container.</p>