REST Controller Spring

Oggi impareremo a scrivere un REST Controller Spring. Come sapete la logica REST(Representational State Transfer) realizza un’architettura client-server di tipo STATELESS per scambiare dati utilizzando il protocollo HTTP.
Il protocollo HTTP REST, in pratica non è altro che l’estensione di una SOA basata su messaggi SOAP, però al contrario di SOAP i messaggi scambiabili prevedono quattro metodi di trasmissione a differenza delle sole GET e POST delle comuni SOA.
Infatti i metodi di trasmissione in un REST Controller Spring sono GET, POST, PUT e DELETE.
Grazie inoltre ad una SOA RESTFul è più semplice implementare delle API complete.
A rigore di completezza sulle SOA RESTFull esse accettano come messaggio inviato sia XML sia JSON contro il solo XML dei web services basati su WSDL.

RESTFul web application Spring

REST Controller Spring

Il JSON (JavaScript Object Notation) permette per l’appunto l’invio/ricezione di oggetti serializzati compatibili con il Model dello strato MVC della nostra ipotetica web-application.
Dopo queste classiche delucidazioni passiamo alla logica della DI (Dependency Injection) che permette mediante l’annotazione @Autowired, l’iniezione di una componente nella classe desiderata, senza dover fare una new, concetto per l’appunto alla base delle Spring Application.

Nei REST controller il codice deve essere minimale ossia deve possedere essenzialmente solo due cose: un Service (interfaccia che astrae) le interazioni con il DB per quanto riguarda quello specifico oggetto del dominio e appunto l’oggetto del dominio.

Il @Service può adottare come tecnica di persistenza ad esempio JPA, ma non è detto che lo utilizzi può utilizzarne anche altri quindi non ci interessa in questo articolo la sua struttura diamo però per assodato che dentro l’implentazione dell’interfaccia dichiarata di tipo @Service vi siano i seguenti tre metodi:

  • @Override public Entity save(Entity e);
  • @Override public Entity findOne(Long id);
  • @Override void delete(ID id);

Supponendo volessimo gestire le CRUD(Create Read Update Delete) appunto della nostra Entity, il REST controller sarà così strutturato.

 
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.domain.Entity;
import org.repository.EntityRepository;
import org.utility.EntityNotFoundException;
 
@RestController
@RequestMapping("/rest/entity")
public class GasRestController {
 
    @Autowired
    private EntityRepository entityRepository;
 
    @RequestMapping(method = RequestMethod.GET)
    public Iterable<Entity> getAll() {
        return entityRepository.findAll();
    }
 
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Entity getOneByID(@PathVariable("id") Long id) {
    	Entity e = entityRepository.findOne(id);
        if (e == null) {
            throw new EntityNotFoundException("Missing Entity");
        }
        return e;
    }
 
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void delete(@PathVariable("id") Long id) {
        entityRepository.delete(id);
    }
 
    @RequestMapping(method = RequestMethod.POST)
    public Entity save(@RequestBody Entity  e) {
        return entityRepository.save(e);
    }
 
    @RequestMapping(method = RequestMethod.PUT)
    public Entity save(@RequestBody Entity  e) {
        Entity e = entityRepository.findOne(id);
        if (e == null) {
            throw new EntityNotFoundException("Missing Entity");
        }
        return entityRepository.save(e);
    }
 
}

Facilissimo vero 🙂 Alcune precisazioni.
1) Per definire un REST Controller in Spring la classe Java deve essere annotata come @RestController.
2) Con @RequestMapping, definiamo la URL della REST API. @RequestMapping può essere anche più specifico a livello di singolo metodo ad esempio possiamo fare questo metodo che risponde all’URL /rest/entity/name.

    @RequestMapping(value="/find/{name}", method = RequestMethod.GET)
    public Entity getOneByName(@PathVariable("name") String name) {
    	Entity e = entityRepository.findByName(name);
        if (e == null) {
            throw new EntityNotFoundException("Missing Entity");
        }
        return e;
    }

3)Ultima chicca evitate i try catch nei REST Controller meglio restituire una fail lanciando un’eccezione che in questo caso mi sono costruito piuttosto che utilizzare quelle di default, per dire che una determinata Entità non è stata trovata.

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
 
/**
 * QEccezione invocata quando non viene trovata l'entità serializzata richiesta
 * dall'utente.
 *
 * @author Gianluca
 */
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class EntityNotFoundException extends RuntimeException {
 
     private static final long serialVersionUID = 1L;
 
    public EntityNotFoundException(String message) {
        super(message);
    }
 
    public EntityNotFoundException() {
        super();
    }
 
}
REST Controller Spring ultima modidfica: 2018-02-18T20:42:28+01:00 da Gianluca Di Vincenzo
Posted in: Java, SOA

By on 18 Febbraio 2018

Tagged: , , , , , , , , , , ,