Creació API Rest Bàsica

Com a punt de partida, crearem una API Bàsica d’una sola taula. Utilitzarem:

  • Spring Boot
  • Spring Data JPA
  • Base de Dades H2 en memòria.
  • Postman, per a proves dels endPoints de la API que gererem.

Mapejarem una taula amb anotacions JPA, crearem un controlador i un servei, i una connexió a H2

Creació del Projecte Spring Boot

Accedim a spring initializer: Initializr

alt text

Automàticament es generaran les dependències gradle necessàries i el projecte es descarregarà en un zip.

Configuració del Projecte.

  • Estructura

La nostra API bàsica tindrà la següent estructura:

alt text

  • 1.- application.properies

L’arxiu de configuració application.properties és un arxiu de propietats que conté valors clau-valor i és utilitzat per configurar l’aplicació Spring Boot. Es pot utilitzar per configurar la connexió a la base de dades, el port del servidor, etc.


# Configurem el port del servidor (per defecte és el 8080)
server.port=8080

# Activem la consola de la base de dades H2
spring.h2.console.enabled=true

# Configuració de la base de dades
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa

# Indicacions per a Hibernate sobre la gestió dels canvis a la base de dades
spring.jpa.hibernate.ddl-auto=update
  • 2.- Connexió amb la Base de Dades H2

Configurem des d’IntelliJ la connexió a la base de dades H2:

  • Crearem un datasource amb el nom que hem posat a l’arxiu application.properties (testdb)
  • La URL de connexió és la que hem posat a l’arxiu de configuració.
  • L’usuari i la contrasenya són els que s’indiquen a l’arxiu de configuració.

Realizem el test de connexió per comprovar que tot està correcte.

alt text

Classe Ciutat - JPA

  • Classe Inicial

public class Ciutat {

    private Long id;
    private String nom;
    private int poblacio;
    private String descripcio;
    private String imatge;

    // Constructors (els 2) , Getters i Setters

}
  • 3.- Entitat Ciutat amb Anotacions JPA

@Entity
@Table (name = "Ciutat")
public class Ciutat {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String nom;
    private int poblacio;
    private String descripcio;
    private String imatge;

    // Constructors, getters i setters
}

Les anotacions JPA més importants són:

Anotació Propòsit Exemples bàsics
@Entity Marca una classe com una entitat JPA, representant una taula en la base de dades. @Entity public class Ciutat { ... }
Defineix la classe Ciutat com a entitat JPA, fent que cada instància corresponga a una fila de la taula de la base de dades.
@Entity public class Usuari { ... }
La classe Usuari serà una altra entitat JPA mapejada a la taula de base de dades per a gestionar informació d’usuaris.
@Table Defineix el nom de la taula i altres configuracions (com índexs o restriccions). @Table(name = "ciutats")
Especifica que aquesta entitat s’emmagatzema en la taula ciutats de la base de dades.
@Table(name = "usuaris", schema = "administracio")
Mapeja l’entitat Usuari a la taula usuaris dins de l’esquema administracio de la base de dades.
@Id Indica quin atribut és la clau primària de l’entitat. @Id private Long id;
Marca l’atribut id com a clau primària de l’entitat.
@Id private String codi;
Marca l’atribut codi com a clau primària si la taula utilitza una clau alfanumèrica en lloc d’un ID numèric.
@GeneratedValue Especifica com es generarà el valor de la clau primària (ex.: autoincremental). @GeneratedValue(strategy = GenerationType.IDENTITY)
Utilitza la configuració d’autoincrement pròpia de la base de dades (com MySQL o PostgreSQL).
@GeneratedValue(strategy = GenerationType.AUTO)
Spring selecciona automàticament l’estratègia adequada segons la base de dades.
@Column Configura propietats específiques d’una columna (nom, si és nullable, longitud, etc.). @Column(nullable = false, length = 50)
Indica que aquesta columna no pot ser nul·la i limita la longitud del text a 50 caràcters.
@Column(name = "nom_ciutat", unique = true)
Canvia el nom de la columna a nom_ciutat i assegura que el seu valor siga únic.
@Transient Marca un atribut que no es guardarà en la base de dades. @Transient private String cache;
Evita que el camp cache siga persistit a la base de dades perquè és temporal.
@Transient private boolean modificat;
L’atribut modificat s’utilitza per processar dades en memòria, però no es guarda en la base de dades.
@Lob Indica que un atribut és un objecte gran, com text llarg o binari. @Lob private String descripcioDetallada;
Permet guardar un text molt llarg, com una descripció extensa, en una columna de tipus CLOB.
@Lob private byte[] imatge;
Permet guardar dades binàries, com imatges o fitxers, en una columna de tipus BLOB.

Repositori - CiutatRepository


@Repository
public interface CiutatRepository  extends JpaRepository<Ciutat,Long> {
}

Controlador- CiutatController



@RestController
@RequestMapping("/ciutats")
public class CiutatController {

    @Autowired
    CiutatRepository ciutatRepository;

    @GetMapping
    public List<Ciutat> obtenirCiutats() {

        return (List<Ciutat>) ciutatRepository.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<Ciutat> obtenirCiutatPerId(@PathVariable(value = "id") Long id) {
        Optional<Ciutat> ciutat = ciutatRepository.findById(id);

        if (ciutat.isPresent()) {
            return ResponseEntity.ok().body(ciutat.get());

        } else {
            return ResponseEntity.notFound().build();
        }
    }


    @PostMapping
    public Ciutat crearCiutat(@RequestBody Ciutat ciutat) {
        return ciutatRepository.save(ciutat);

    }

        @DeleteMapping("/{id}")
    public void eliminarCiutat(@PathVariable Long id) {
        ciutatRepository.deleteById(id);
    }


    @PutMapping("/{id}")
    public ResponseEntity<Ciutat> actualitzarCiutat(@PathVariable Long id, @RequestBody Ciutat ciutatActualitzada) {
        Optional<Ciutat> optionalCiutat = ciutatRepository.findById(id);

        if (optionalCiutat.isPresent()) {
            Ciutat ciutat = optionalCiutat.get();
            ciutat.setNom(ciutatActualitzada.getNom());
            ciutat.setPoblacio(ciutatActualitzada.getPoblacio());
            ciutat.setDescripcio(ciutatActualitzada.getDescripcio());
            ciutat.setImatge(ciutatActualitzada.getImatge());

            return ResponseEntity.ok().body(ciutatRepository.save(ciutat));
        } else {
            return ResponseEntity.notFound().build();
        }
    }

}

Prova de l’API

Una volta creat el projecte, l’executem i provem en el navegador:

  • http://localhost:8080

Després connectem el projecte amb Postman i inserim dades amb POST

alt text