Invocazione di Servizi RESTful con RestTemplate

Esistono diverse tecnologie per l’implementazione di un client RESTful in java, come ad esempio la RESTEasy Client API, ma la libreria RestTemplate disponibile nel modulo Spring Web è probabilmente quella più semplice da implementare. In questo post mostriamo un esempio completo, basato su Spring Boot, che implementa un insieme di microservizi consumati da un client. In particolare due miscorservizi che sono responsabili della generazione, rispettivamente, di un numero random intero ed di una operazione aritmetica da eseguire. Un terzo microservizio, invece, invoca i due precedenti per eseguire il calcolo l’operazione selezionata.

Per una rapida introduzione alla tecnologia Spring Boot si rimanda all’articolo Primi Passi con Spring Boot.

Il Progetto

Per semplicità strutturiamo il codice come un progetto maven multimodulo. Ciascun modulo è un progetto Spring Boot ed il progetto principale contiene tutte le dipendenze necessarie ai moduli.

Il pom.xml del progetto padre contiene quindi sia il riferimento a spring-boot-starter-parent che la dipendenza a spring-boot-starter-web.

Random Generator

I due microservizi, responsabili della generazione dei numeri casuali e dell’operazione aritmetica sono, caratterizzati da due classi controller, quindi annotate con @RestController, che implementano un unico metodo http GET il quale restituisce un json  con le informazioni generate.

{
“value” : “-”
}
{
“value” : 93
}

Il comportamento dei due servizi è parametrizzato attraverso due file di configurazione application.yml in cui è anche indicata la porta in cui sono esposti. Questo perchè, trattandosi di applicazioni Spring Boot separate, ciascun servizio dovrà essere in ascolto su porte differenti.

 

Number Generator

Le classi caratteristiche del generatore di numeri casuali sono due: un coltroller ed una property holder.

L’utilizzo dell’annotazione @ConfigProperties probabilmente merita un articolo a parte, ma per ora ci basti sapere che Spring riconosce la classe NumberGeneratorProperties come un contenitore delle proprietà esternalizzate nel file application.yml.

Operator Generator

In modo analogo anche il secondo microservizio è caratterizzato da un controller ed un property holder.

Consumo dei Servizi REST

Come riportato nel javadoc, RestTemplate è il componente centrale di Spring per l’accesso in modo sincrono ai servizi HTTP. Esso semplifica la comunicazione con i server applicando i principi RESTful, gestendo le connessioni HTTP, e lasciando all’applicazione il solo compito di fornire l’URL al servizio, eventualmente con template variable, e l’estrazione dei risultati.

Il framework non fornisce un bean di tipo RestTemplate ma un componente RestTemplateBuilder che, secondo necessità, può essere iniettato ed utilizzato per ottenere un bean di tipo RestTemplate da configurare secondo necessità. In generale è buona norma avere un bean differente per ciascun servizio da invocare anche perchè ogni servizio avrà caratteristiche specifiche.

Nel nostro caso per il progetto calculator che invoca i microservizi numbergenerator e operatorgenerato abbiamo preferito utilizzare un unico bean RestTemplate generato nella classe  CalculatorApplication e per poi essere iniettato nei service all’occorrenza.

L’applicazione include poi due service: NumberGeneratorService e OperatorGeneraatorService, che utilizzano il bean RestTemplate per l’invocazione del relativo microservizio.

Come si nota sono molto simili e, come anticipato, l’uso del bean richiede esclusivamente di fornire l’url al servizio chiamato. Il metodo getForEntity si occupa di eseguire la GET sull’URL specificato ed a convertire il json ottenuto nell bean indicato: RandomInteger piuttosto che RandomOperator.

I due service così implementati sono poi utilizzati da un CalculatorController il quale genera l’output utilizzando il parser di Spring per le espressioni SpEL.

Esecuzione del Progetto

Per eseguire i tre progetti è sufficiente eseguire il task maven spring-boot:run fornito dal plug-in spring-boot-maven-plugin che abbiamo inserito nel pom.xml del progetto principale. Si noti che il task va eseguito su tutti e tre i progetti e gli url su cui i servizi saranno esposti sono:

Utilizzo di RestTemplate

Dopo aver mostrato questo semplice esempio vediamo alcuni aspetto “avanzati” nell’utilizzo di tale componente, A cominciare dai metodo che consentono di eseguire le diverse chiamate HTTP:

HTTP RESTTEMPLATE
DELETE delete(String, String...)
GET getForObject(String, Class, String...)
HEAD headForHeaders(String, String...)
OPTIONS optionsForAllow(String, String...)
POST postForLocation(String, Object, String...)
PUT put(String, Object, String...)

Abbiamo poi parlato della possibilità di utilizzare l’URI Templating per la indicazione dell’URL del servizio invocato. Tutti i metodi sopra indicati ammettono come primo parametro l’URL che può contenere dei placeholder contenuti tra parentesi graffe. Il valore di tali parametri può essere indicato o attraverso un array di parametri nel metodo o mediante una mappa di stringhe.

Ad esempio se ne nostro servizio di generazione di un numero random avessimo avuto come parametro di input il  range di valori richiesti, in termini di valore massimo e minimo, l’invocazione avrebbe potuto essere:

Infine gli oggetti passati e restituiti dai metodi getForObject(), postForLocation() e put() sono convertiti in richieste HTTP e da risposte HTTP da specifici HttpMessageConverters. I convertitori per i tipi MIME principali e i tipi Java sono registrati per impostazione predefinita, ma è anche possibile scrivere il proprio convertitore e collegarlo al RestTemplate. Al sito della documentazione ufficiale https://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate è mostrato un esempio di convertitore per il recupero di immagini dal servizio Flickr.

Codice Sorgente

Il codice sorgente completo con tutti gli esempi presentati è scaricabile qui restconsumer.

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 2

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!