Construire des API REST avec Spring MVC et RestTemplate

REST (Representational State Transfer) est souvent confondu avec un simple mécanisme RPC utilisant des URL HTTP. En réalité, REST et RPC suivent des philosophies opposées : RPC est orienté action, tandis que REST est orienté ressource. REST modélise les entités métier sous forme de ressources et les manipule via des verbes HTTP standards.

Le terme peut être décomposé en trois notions :

  • Representational : une ressource peut être exposée sous différents formats (JSON, XML, HTML, etc.) selon les besoins du client.
  • State : on s’intéresse à l’état de la ressource plutôt qu’aux actions à effectuer.
  • Transfer : l’état de la ressource est transféré entre le serveur et le client, dans une représentation adaptée.

Concrètement, un client peut demander une ressource au format JSON, et le service REST la lui fournit. S’il la demande en XML, il reçoit du XML. Les ressources sont identifiées par des URL, et les opérations sont mappées sur les méthodes HTTP : GET (lecture), POST (création), PUT ou PATCH (mise à jour), DELETE (suppression). PUT est idempotent, contrairement à POST qui peut être utilisé pour des opérations ne correspondant pas strictement aux autres verbes.

L’architecture RESTful sépare clairement le frontend, sans état métier, du backend qui gère l’état et expose des interfaces de transition. Le frontend ne possède que des représentations des ressources, et toute modification de l’état passe par un transfert (appel à l’API).

Spring MVC fournit plusieurs mécanismes pour exposer des ressources REST :

  • Prise en charge de toutes les méthodes HTTP (GET, POST, PUT, DELETE, etc.).
  • Conversion de messages via des HttpMessageConverter.
  • Annotations dédiées (@RestController, @RequestBody, @ResponseBody…).
  • RestTemplate pour consommer des API REST côté client.

Conversion de messages

La conversion de messages permet de produire directement la représentation d’une ressource à partir des données renvoyées par le contrôleur, sans passer par une vue. Spring propose plusieurs convertisseurs prêts à l’emploi, par exemple MappingJackson2HttpMessageConverter pour le format JSON.

Exemple de configuration XML avec déclaration de convertisseurs :

<mvc:annotation-driven>
   <mvc:message-converters>
       <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="supportedMediaTypes">
               <list>
                   <value>application/json;charset=UTF-8</value>
                   <value>text/plain;charset=UTF-8</value>
               </list>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

Annotations REST de Spring MVC

@PathVariable lie une variable de l’URL à un paramètre de méthode.
@ResponseBody indique que la valeur de retour doit être sérialisée par un convertisseur de message plutôt que résolue par une vue.
@RequestBody désérialise le corps de la requête en un objet Java à l’aide d’un convertisseur.
@RestController est une annotation de niveau classe qui combine @Controller et @ResponseBody : toutes les méthodes héritent de ce comportement.
@ResponseStatus permet de spécifier le code de statut HTTP de la réponse.
ResponseEntity offre un contrôle fin sur la réponse (headers, statut, corps).

Exemple de contrôleur REST avec ResponseEntity :

@RestController
@RequestMapping("/api/clients")
public class ClientController {

   @PostMapping(consumes = "application/json")
   public ResponseEntity<ClientDto> creerClient(@RequestBody ClientDto client, UriComponentsBuilder ucb) {
       ClientDto saved = clientService.enregistrer(client);
       HttpHeaders headers = new HttpHeaders();
       URI location = ucb.path("/{id}").buildAndExpand(saved.getId()).toUri();
       headers.setLocation(location);
       return new ResponseEntity<>(saved, headers, HttpStatus.CREATED);
   }
}

RestTemplate est le client HTTP fourni par Spring pour interagir avec des API REST. Il propose de nombreuses méthodes surchargées, correspondant aux verbes HTTP. Les signatures principales acceptent souvent une URL sous forme de chaîne avec des paramètres variables, ou un objet URI.

Quelques exemples de surcharges de getForObject :

// URL avec arguments variables (varargs)
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables);

// URL avec paramètres dans une Map
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);

// Utilisation d'un objet java.net.URI
public <T> T getForObject(URI url, Class<T> responseType);

Les opérations de base incluent :

  • postForEntity, postForObject, postForLocation – création d’une ressource.
  • getForEntity, getForObject – lecture.
  • put – mise à jour.
  • delete – spupression.
  • headForHeaders, optionsForAllow – métadonnées.
  • exchange et execute – méthodes plus génériques permettant un contrôle complet.

Dans les méthodes postForObject, le paramètre request peut être un objet simple (le corps de la requête) ou une instance de HttpEntity (incluant en-têtes et corps). La version avec Map permet de résoudre les variables d’URL.

// Exemple avec un objet HttpEntity
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<ClientDto> entity = new HttpEntity<>(dto, headers);
ClientDto result = restTemplate.postForObject("http://example.com/api/clients", entity, ClientDto.class);

Pour une référence complète et des exemples d’intégration, consultez le dépôt : https://github.com/JMCuixy/SpringMvcForRest.

Étiquettes: Spring MVC resttemplate Jackson RESTful API REST

Publié le 9 août à 16h23