Blog

Hosting REST endpoints next to your Vaadin UI

By  
Matti Tahvonen
Matti Tahvonen
·
On Jul 24, 2024 5:16:14 PM
·

When building your UI with Vaadin, you need no REST endpoints. With Vaadin Flow, you don’t even need to think about what gets transferred between your browser and the server. But it is common for your Vaadin application to expose some REST endpoints, for example, to separate services or complementary native clients.

Sometimes, even your Vaadin UI itself might be the client for resources like images or videos exposed with REST libraries. From time to time, I see questions like, "Can you host REST endpoints with Vaadin?" You sure can. The more interesting question is how to do it and what the pitfalls are.

In this tutorial, we'll discuss two main approaches: hosting REST endpoints within the same module as your Vaadin UI or using a separate artifact for REST services. Each method has its pros and cons, of course. Let's take a look!

Expose REST endpoints directly from the same module

In small to medium-sized apps or in “monoliths,” a tempting solution is to fit both your Vaadin UI and the REST endpoints to the same Java server module (war file or standalone app built with tools like Spring Boot or Quarkus). This can also be tempting if your REST endpoints are small and simple, kind of not deserving a separate module to your system. 

Here is a trivial JAX-RS REST example, which you could drop to your Quarkus or CDI application right next to our Vaadin UIs. With Spring Boot, you probably want to use @RestController which typically has a higher priority over Vaadin URL mappings.

@Path("/hello")
public class GreetingResource {

   @GET
   @Produces(MediaType.TEXT_PLAIN)
   public String hello() {
       return "Hello from JAX-RS";
   }
}

This approach can be a good choice if your data lives in the JVM memory and is shared by both the Vaadin UI and the REST endpoint. It is also very well-performing in case you need the data displayed live on the Vaadin UI. There is no need for inter-service communication within your system, which often comes with a performance penalty.

As already mentioned, Vaadin works well in this kind of use case with the most common Java libraries for REST services, but there are a couple of common pitfalls:

  • Vaadin UIs and your REST endpoints are commonly “competing” for similar URL patterns. For example, if your main view utilizing HasUrlParameter is mapped to “/”  it will “hijack” all HTTP requests from a JAX-RS endpoint and vice versa with Spring REST endpoints.
  • Security configurations can become more complicated. For example with our Spring Boot examples, the Security configuration is rather strict by default (that’s a good thing), and can easily block the requests you wish to receive at the REST endpoint. This is by far the most common issue, why certain new Vaadin users think the Vaadin UI is allergic to REST endpoints. The “right configuration” does not exist; it depends on the requirements of your REST endpoints and Vaadin views.

Some tips to get things working: 

  • For developers, it may be clearest to map the Vaadin part to, for example, “/ui*” and REST endpoints to “/api/*. In Spring Boot, the magic configuration is vaadin.url-mapping.
  • Instruct your Vaadin app to ignore certain URLs.
  • Enable logging for Spring Security
  • Customize the Spring Security configuration, if needed, carefully based on your requirements. The requirements of your REST endpoint can be totally different than for the actual web UI built with Vaadin. Some pointers toward common setups

Separate artifact for REST services

In highly modular systems (including systems built as microservices), the most natural approach is to use a completely different artifact for REST endpoints. In this kind of system, your data is pretty much always in a separate shared database or service, which is then utilized by both Vaadin UI and REST endpoints. In this kind of setup, a good approach is to use a separate deployment artifact for REST endpoints.

Deployment considerations

With traditional WAR deployments, the artifacts can be deployed on the same server, but they’d still be logically separate modules. REST services could even be implemented with a different programming language and execution environment. A more common scenario is, though, that your Vaadin UI and the artifact providing the REST services both run on JVM and utilize some shared modules for DTOs and to access backend systems.

In this scenario, there are naturally no conflicts between your Vaadin views and REST endpoints. For example, with security configurations, there is now a much smaller chance of mixing relevant rules between your REST endpoint and resources accessed by the Vaadin UI.

Architectural implications

Architecturally, this often implies that other pieces in your apps should be separate services as well, like moving authentication and authorization to a separate service shared by both REST endpoints and Vaadin UI. Your system most probably also needs a more complex hosting setup, and the problem of “competing URLs” described in the previous step has just moved from Java apps to that part of your system.

Wrapping up

In this tutorial, we've explored the two main approaches to integrating REST endpoints with your Vaadin UI: hosting them within the same module or using a separate artifact for REST services. Each method has its benefits and challenges, from potential URL conflicts to security configurations. Understanding these approaches helps you make informed decisions for your Vaadin applications.

Need more help or have any questions about integrating REST endpoints with your Vaadin UI? Reach out to us in the Vaadin community forum. Happy coding!

Matti Tahvonen
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies. You can follow him on Twitter – @MattiTahvonen
Other posts by Matti Tahvonen