Spring Boot und externe Anwendungen

tiny-tool.de

tiny-tool.de

In modernen Anwendungen ist es häufig erforderlich, Daten aus externen Quellen zu konsumieren, sei es über öffentliche APIs oder Microservices innerhalb eines größeren Systems. Spring Boot bietet Entwicklern verschiedene Möglichkeiten, solche externen Services zu integrieren, und in diesem Artikel zeigen wir drei der beliebtesten Optionen: RestTemplate, WebClient und OpenFeign. Wir betrachten, wie diese HTTP-Clients verwendet werden können, um Daten von externen Services abzurufen, welche Vor- und Nachteile sie bieten und wann welcher Client sinnvoll ist.

Exemplarischer User-Service

In allen drei Varianten nutzen wir ein gemeinsames Interface, um die Konsistenz und Austauschbarkeit der Implementierungen zu wahren. Dies ermöglicht es uns, den HTTP-Client flexibel zu wechseln, ohne den Code des restlichen Systems anzupassen.

package de.zeus.example.webclient.service;

import de.zeus.example.webclient.model.User;
import java.util.List;

public interface UserService {
  List getUsers();
}

1. RestTemplate

RestTemplate ist ein einfacher, synchroner HTTP-Client und war über viele Jahre hinweg die Standardlösung in Spring-Anwendungen. Obwohl er inzwischen veraltet ist, wird er nach wie vor in vielen Anwendungen verwendet und bietet eine intuitive API für Entwickler, die mit synchronen Programmiermustern vertraut sind.

Implementierung mit RestTemplate

package de.zeus.example.webclient.service;

import de.zeus.example.webclient.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
@Profile("resttemplate")
public class RestTemplateUserService implements UserService {
  private static final String URL = "https://jsonplaceholder.typicode.com/users";

  @Autowired
  private RestTemplate restTemplate;

  @Override
  public List getUsers() {
    return Arrays.stream(Objects.requireNonNull(restTemplate.getForObject(URL, User[].class))).toList();
  }
}

Vorteile:

  • Einfach zu verwenden: RestTemplate ist leicht zu verstehen und bietet eine einfache API für synchrones HTTP-Handling.
  • Breit unterstützte Bibliothek: Viele Bibliotheken und Projekte haben bereits Integration mit RestTemplate.
  • Gut für kleine und einfache Anforderungen: Für einfache synchrone API-Aufrufe ist RestTemplate eine solide Wahl.

Nachteile:

  • Veraltet: Ab Spring 5 wird RestTemplate nicht mehr aktiv weiterentwickelt, und die Empfehlung geht in Richtung WebClient.
  • Nicht reaktiv: Da RestTemplate vollständig synchron arbeitet, ist es nicht für hochskalierbare, asynchrone Anwendungen geeignet.
  • Fehlende Flexibilität bei modernen Anforderungen: Es fehlen einige der modernen Funktionen, die WebClient bietet, wie z. B. Backpressure oder die Integration in reaktive Streams.

2. WebClient

WebClient ist der empfohlene HTTP-Client in Spring 5 und bietet sowohl synchrone als auch asynchrone, nicht-blockierende HTTP-Aufrufe. Es wurde entwickelt, um moderne Anforderungen an Skalierbarkeit und Performance zu erfüllen und kann nahtlos in reaktive Anwendungen integriert werden.

Implementierung mit WebClient

package de.zeus.example.webclient.service;

import de.zeus.example.webclient.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.List;

@Service
@Profile("webclient")
public class WebClientUserService implements UserService {
  private static final String URL = "https://jsonplaceholder.typicode.com/users";

  @Autowired
  private WebClient webClient;

  @Override
  public List getUsers() {
    return webClient.get()
      .uri(URL)
      .retrieve()
      .bodyToFlux(User.class)
      .collectList()
      .block();
  }
}

Vorteile:

  • Reaktiv und nicht-blockierend: WebClient unterstützt vollständig asynchrone Programmierung, was ihn ideal für hochskalierbare Anwendungen macht.
  • Flexibel: WebClient ist extrem flexibel und unterstützt viele moderne HTTP-Funktionen wie Streaming, Backpressure und Zeitlimits.
  • Integration mit Reactor: Perfekt für reaktive Spring-Anwendungen, die auf Project Reactor basieren.

Nachteile:

  • Komplexität: WebClient ist mächtiger, aber auch komplexer als RestTemplate, besonders wenn man reaktive Programmierung nicht gewohnt ist.
  • Performance-Overhead bei kleinen Anwendungen: Wenn du nur einfache, synchrone API-Aufrufe machst, kann der zusätzliche Overhead von WebClient unnötig sein.

3. OpenFeign

OpenFeign ist eine deklarative HTTP-Client-Bibliothek, die sich ideal für die Kommunikation zwischen Microservices eignet. Feign bietet eine klare und einfache API, um externe Services anzusprechen, ohne dass der Entwickler explizit die HTTP-Logik behandeln muss.

Implementierung mit OpenFeign

package de.zeus.example.webclient.service;

import de.zeus.example.webclient.client.UserFeignClient;
import de.zeus.example.webclient.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Profile("feignclient")
public class OpenFeignUserService implements UserService {
  @Autowired
  private UserFeignClient userFeignClient;

  @Override
  public List getUsers() {
    return userFeignClient.getUsers();
  }
}

Vorteile von OpenFeign:

  • Deklarativer Ansatz: Der Client kann einfach durch Schnittstellen definiert werden.
  • Integriert in Spring Boot: Die Integration in Spring Boot ist nahtlos und ermöglicht die einfache Verwendung von Feign-Clients.
  • Ideal für Microservices: Besonders geeignet für Microservices, die miteinander kommunizieren.

Nachteile von OpenFeign:

  • Standardmäßig synchron: OpenFeign arbeitet standardmäßig synchron, was in einigen Fällen nicht optimal ist.
  • Begrenzte Flexibilität: Für komplexere Anforderungen (wie Streaming oder asynchrone Verarbeitung) kann Feign an seine Grenzen stoßen.

Implementierung eines FeignClients

Bevor OpenFeign verwendet werden kann, muss der Feign-Client explizit definiert werden:

package de.zeus.example.webclient.client;

import de.zeus.example.webclient.model.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient(name = "userfeignclient", url = "https://jsonplaceholder.typicode.com")
public interface UserFeignClient {
  @GetMapping("/users")
  List getUsers();
}

Aktivieren von OpenFeign

Damit OpenFeign korrekt funktioniert, muss die Hauptklasse der Spring Boot Anwendung mit der Annotation @EnableFeignClients versehen werden:

package de.zeus.example.webclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class WebclientExampleApplication {
  public static void main(String[] args) {
    SpringApplication.run(WebclientExampleApplication.class, args);
  }
}

Fazit: Welcher Client passt zu deinem Projekt?

  • RestTemp.late: Verwende diesen Client, wenn du eine einfache, synchrone HTTP-Kommunikation benötigst oder mit bestehenden Anwendungen arbeitest, die bereits auf RestTemplate setzen.
  • WebClient Extrem flexibel und bietet sowohl reaktive als auch blockierende Verarbeitung. In unserem Beispiel nutzen wir die blockierende Verarbeitung für Einfachheit, aber WebClient kann ebenso nicht-blockierend arbeiten, was ihn zur idealen Wahl für moderne, hochskalierbare, reaktive Anwendungen macht..
  • OpenFeign: Ideal für Microservice-Architekturen, in denen du eine deklarative und einfache Möglichkeit suchst, um REST-Clients zu definieren.

Für jedes Projekt gibt es also den passenden Client, und die Wahl hängt stark von den spezifischen Anforderungen an Skalierbarkeit, Flexibilität und Einfachheit ab.

Relevante Links und Alternativen zu HTTP-Clients

Wenn du tiefer in das Thema Spring Boot und HTTP-Clients eintauchen möchtest oder Alternativen zu den in diesem Artikel vorgestellten Clients suchst, findest du hier einige hilfreiche Ressourcen und alternative HTTP-Clients:

Offizielle Dokumentationen:

Weitere Alternativen

Neben den hier vorgestellten HTTP-Clients gibt es noch einige weitere Alternativen, die je nach Anwendungsfall ebenfalls sinnvoll sein können:

  • Apache HttpClient: Eine sehr bekannte und stabile Bibliothek, die für viele Java-Entwickler eine Standardlösung für komplexere HTTP-Interaktionen ist. Sie unterstützt sowohl synchrone als auch asynchrone Aufrufe.
  • Spring RestTemplate Dokumentation: Ein moderner HTTP-Client, der leichtgewichtig und sehr performant ist. Besonders in Android-Anwendungen und bei der Integration von RESTful-Services weit verbreitet.
  • Vert.x Web Client: Ein reaktiver HTTP-Client, der auf dem Vert.x-Framework basiert. Besonders geeignet für Anwendungen, die hohe Skalierbarkeit und reaktive Verarbeitung benötigen.
  • Jetty HttpClient: Teil des Jetty-Projekts und bekannt für seine asynchrone, nicht-blockierende Implementierung. Oft verwendet für hochperformante, skalierbare Anwendungen.