Immagine descrittiva del post

In questo articolo imparerai a creare servizi web RESTful utilizzando Spring Boot. Vedrai come connettere l’applicazione ad un database e come implementare un’ambiente di persistenza definendo entità, creando servizi CRUD e controller.

Non farti spaventare da quello che hai appena letto, tra poco capirai di cosa si tratta… Continua a leggere.

 

Servizi Web RESTful

Senza entrare troppo nel merito delle definizioni (il web ne è pieno), cerchiamo di capire cosa si intende per Servizio Web RESTful.

I Web Service (servizi web) sono applicazioni software che, indipendentemente dal linguaggio di programmazione o piattaforma hardware, possono essere utilizzate da altre applicazioni attraverso l’interfaccia che espongono. L’interfaccia esposta dai Servizi Web permette di elaborare richieste (servizio) attraverso i protocolli del web come HTTP (da qui il nome Web Service).

Per un Web Service, REST è l’insieme dei principi per rappresentare la trasmissione delle risorse elaborate, tramite HTTP. Un principio fondamentale in REST è proprio l’esistenza di risorse alle quali si può accedere tramite un identificatore globale (un URI).

 

Per quanto detto, creare un Servizio Web RESTful significa adottare un approccio in cui le risorse sono gli elementi principali e sappiamo che l’effetto su una risorsa si basa su un metodo HTTP. Questo vuol dire che, una volta individuata la risorsa tramite URI, sappiamo quale operazione verrà svolta su di essa attraverso il metodo utilizzato nella chiamata HTTP.

Vediamo come tradurre tutto questo in applicazioni Spring Boot.

 

Creare Servizi Web RESTful in Spring Boot

Nell’immagine seguente è rappresentato il modello architetturale di un Web Service Spring.

Rappresentazione degli strati dell'architettura di un Web Service Spring
Strati dell'architettura di un Web Service Spring

Andando per analogie, nello schema:

  • le risorse vengono rappresentate da un modello di dominio e rese pubbliche tramite oggetti DTO per essere trasferite.
  • lo strato Web rappresenta l’interfaccia pubblica per l’identificazione delle risorse, implementata dai controller.
  • lo strato Service definisce le operazioni (ad esempio CRUD) sulle risorse descritte nell’interfaccia, comunicando con uno strato Repository che accede ai dati.
 

Bootstrap di un'applicazione Spring Boot come Servizio Web RESTful

In un post precedente ho spiegato come creare un nuovo progetto Spring Boot in pochi minuti. Il risultato è un’applicazione semplice, ma che rappresenta la base per lo sviluppo di un’applicazione un pò più complessa come quella che vedrai tra poco.

 

Aggiungere le dipendenze

Spring Boot mette a disposizione un’insieme di librerie e configurazioni che facilitano lo sviluppo di servizi web tramite i pacchetti starter, reperibili attraverso le dipendenze Maven da aggiungere al file pom.xml.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
 

Configurare la connessione al database

Per memorizzare le risorse sulla quale eseguire operazioni (CRUD) si può utilizzare un database.

 

Definire una risorsa

Le risorse rappresentano dati. Attraverso i servizi vogliamo eseguire operazioni CRUD sui dati presenti su un database.

Scegliendo Java, possiamo definire un tipo di dato facendo uso di JPA per gestirne la persistenza. 

Come esempio, crea una classe Java nominata Team per la rappresentazione di una squadra.

@Entity
public class Team {

    private Long id;
    private String name;
    private int members;
    private String primaryColor;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getMembers() {
        return members;
    }

    public String getPrimaryColor() {
        return primaryColor;
    }
    
    // setter methods
}

Questa è la classe Entity che rappresenta il tipo di dato Team mappato sul database, ma non è l’unico modo per rappresentare un’entità. Definisci una classe DTO per una sua rappresentazione all’esterno dell’applicazione.

public class TeamDto implements Serializable {

    private String name;
    private int members;
    private String primaryColor;
    
    // getter and setter
}
 

Definire le operazioni CRUD sulle risorse

Le operazioni CRUD (ma non solo) sui dati vengono svolte dal Service. Spring Boot mette a disposizione un’annotazione adatta al ruolo che vuole ricoprire una classe. 

Ad esempio, puoi creare una classe TeamService nella quale definire le operazioni su l’entità Team vista poco fa.

Prima di fare questo, utilizza l’interfaccia JpaRepository della libreria org.springframework.data.jpa (già vista nell’articolo: Comunicare con il database in un’applicazione Spring Boot) per definire l’interfaccia TeamRepository.

@Repository
public interface TeamRepository extends JpaRepository {
}
@Service
public class TeamService {

    @Autowired
    private TeamRepository teamRepository;

    @Autowired
    private TeamMapper teamMapper;

    public TeamDto getById(Long id) {
        Optional<Team> resultOpt = teamRepository.findById(id);
        return resultOpt.isPresent() ? teamMapper.toDto(resultOpt.get()) : null;
    }

    public void create(TeamDto dto) {
        teamRepository.save(teamMapper.toEntity(dto));
    }
}

Nella classe TeamService sono definiti due metodi: getById e create.

Come si intuisce dai nomi, i metodi servono rispettivamente per ottenere una risorsa Team attraverso il suo ID e aggiungerne una nuova. Le effettive operazioni sui dati vengono svolte dalla classe Repository creata.

Come vedi, TeamRepository non dichiara nessun metodo, ma estendendo l’interfaccia JpaRepositoty ne eredita i metodi.

Come ultimo aspetto, TeamService utilizza una classe Mapper che svolge la funzione di trasformare il dato nella sua nuova rappresentazione. Per completezza, crea la classe TeamMapper oppure utilizza una qualsiasi libreria di mapper se può facilitarti il lavoro, a te la scelta.

@Component
public class TeamMapper {

    public TeamDto toDto(Team entity) {
        TeamDto dto = new TeamDto();
        dto.setName(entity.getName());
        dto.setMembers(entity.getMembers());
        dto.setPrimaryColor(entity.getPrimaryColor());
        return dto;
    }

    public Team toEntity(TeamDto dto) {
        Team entity = new Team();
        entity.setName(dto.getName());
        entity.setMembers(dto.getMembers());
        entity.setPrimaryColor(dto.getPrimaryColor());
        return entity;
    }
}
 

Definire un'interfaccia pubblica per elaborare le richieste

L’ultimo passo nella realizzazione del tuo Web Service RESTful consiste nel definire l’interfaccia da esporre per le richieste esterne. 

Si tratta di una classe Java in cui dovrai definire le URI che identificano unicamente una risorsa e assegnare i metodi HTTP adatti all’operazione da svolgere (ti ricordi quanto detto a proposito di REST?).

@RestController è un’annotazione Spring Boot conveniente per l’implementazione di controller RESTful. È un componente particolare che, tra le altre cose, converte la risposta in formato JSON (default) o XML, come voluto da una tipica applicazione REST. @RestController è tipicamente utilizzata in combinazione con @RequestMapping.

@RestController
@RequestMapping("api/v1/team")
public class TeamController {

    @Autowired
    private TeamService teamService;

    @GetMapping("/{id}")
    public ResponseEntity getById(@PathVariable(name = "id") Long id) {
        return ResponseEntity.ok(teamService.getById(id));
    }

    @PostMapping
    public ResponseEntity create(@RequestBody TeamDto dto) {
        teamService.create(dto);
        return ResponseEntity.noContent().build();
    }
}

Un RestController come quello visto è in grado di elaborare richieste a partire dall’indirizzo /api/v1/team. Senza però definire le operazioni da eseguire sulla risorsa tramite metodi HTTP (post, get ecc..), il controller non sarà in grado di compiere nessuna attività. Utilizza le annotazioni @GetMapping e @PostMapping per completare l’implementazione del controller REST.

Nell’esempio:

  • POST /api/v1/team :  riceve un oggetto come body della richiesta per aggiungere un Team
  • GET /api/v1/team/12345 : restituisce la risorsa Team con id univoco 12345 in formato JSON

 

Hai appena visto come creare servizi web RESTful con Spring Boot

Prossimi passi?

A questo punto potrai realizzare in autonomia il tuo Web Service. Un ulteriore passo consiste nel mettere in sicurezza le APIdocumentarle.

Per qualsiasi chiarimento inserisci un commento qui sotto.

Quasi dimenticavo! Per ringraziarti, ho caricato per te il codice di questo esempio su GitHub a questo indirizzo.