Cómo construir una API Rest con Spring Boot usando MySQL y JPA

¡Hola a todos! Durante el año pasado, estuve aprendiendo JavaScript para el desarrollo web de pila completa. Para variar, comencé a dominar Java, el poderoso lenguaje orientado a objetos.

En ese caso, encontré un marco muy limpio y elegante llamado Spring Boot para construir un back-end.

Anteriormente, en el desarrollo de JavaScript, usé:

  1. Mongoose: un ORM (mapeo relacional de objetos) para Mongo DB
  2. Sequelize: un ORM para MySQL

Para el desarrollo relacionado con Java, hay muchos ORM como Hibernate, JPA (API de persistencia de Java) y consultas orientadas a objetos de Java.

Elijo construir con JPA, que se usa tradicionalmente en aplicaciones Java.

Fue muy interesante y tardé aproximadamente una semana en terminar, ya que tuve que aprender Spring Boot (hay muchas anotaciones “ @ ” y otras cosas interesantes que aprender), JPA e Hibernate en el camino.

Toda esta magia se realiza principalmente mediante las anotaciones ( símbolo " @ ") utilizadas en Spring Boot.

Creación de un proyecto Spring Boot Maven

Creemos una aplicación de proyecto Spring Boot Maven usando este enlace.

" Maven " es una herramienta de gestión de proyectos que se utiliza para gestionar la gestión de dependencias. Es como Node Package Manager ( NPM ) en el entorno de desarrollo JS.

Tenemos package.json en NodeJS para la gestión de dependencias y pom.xml en Spring Boot para la gestión de dependencias.

En Grupo, escriba el nombre que desee. Por lo general, el nombre de dominio de la organización se escribe de derecha a izquierda.

Por ejemplo, nuestro nombre de dominio es www.javaAPI.com, por lo que el nombre del grupo podría ser com.javaAPI.www

Luego, en el Artefacto, escriba el nombre de la carpeta que desee .

En el lado derecho, agregue las siguientes dependencias:

  1. WEB: para usar las dependencias de Spring (el marco más antiguo de Spring Boot utilizado para desarrollar aplicaciones web)
  2. JPA - API de persistencia de Java
  3. MYSQL

Luego haga clic en "Generar proyecto". Encontrará un archivo rar, extráigalo. Luego abra esa carpeta en su IDE favorito.

Haga clic en com.rest.API y encontrará un archivo ApiApplication.java de la siguiente manera:

package com.rest.API; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }

Este código es suficiente para iniciar su servidor. Normalmente, el arranque de primavera se ejecuta en localhost: 8080 .

Escriba su terminal de la siguiente manera:

mvn spring-boot: ejecutar

Vea su localhost ejecutándose en el navegador web en el puerto 8080. Parece en blanco porque todavía no hemos hecho nada.

Exploremos los archivos y sus etiquetas.

Si echas un vistazo al archivo pom.xml, es posible que notes que las dependencias que colocaste al crear la aplicación en Spring Initialize como MySQL, JPA y Web estarán dentro de un cy> etiqueta.

Las dependencias de iniciador y probador son el núcleo para crear la aplicación Spring Boot para servir en el servidor.

Ahora, vayamos a APIApplication.java, que es el archivo principal.

package com.rest.API; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }

Aquí el nombre del paquete está en la primera línea del código. Con ese nombre de paquete, puede importar cualquier clase, método o instancias en otro archivo de paquete.

Después de eso, se importan dos módulos del paquete "org.springframework.boot".

  1. SpringApplication
  2. SpringBootApplication

Dado que Spring boot es el último marco de desarrollo de aplicaciones de Spring, necesita los paquetes de Spring Application, así como sus paquetes específicos.

Después de eso, se usa la anotación @SpringBootApplication . Esta anotación consta de una anotación que se utiliza en Spring:

  1. @Component : le dice al compilador que la siguiente clase es un componente que debe incluirse al compilar toda la aplicación.
  2. @ComponentScan : este hace el escaneo de los paquetes que vamos a usar en la siguiente clase de Java.
  3. @EnableAutoConfiguration : habilita el mecanismo de configuración automática de Spring Boot para importar módulos importantes para que se ejecute Spring Boot.

Estas son las anotaciones que se utilizan para iniciar la aplicación Spring Boot para que se ejecute en un servidor.

Aquí hay un artículo que he escrito sobre Anotación y sus usos en Java.

Creemos un modelo para nuestros datos

Creemos una clase de modelo para guardar, recuperar, actualizar y eliminar los detalles de un libro.

Para eso, tengo que crear un nuevo paquete llamado modelo y dentro de él crear una clase Book.java para poner mi código.

package com.rest.API.model; import javax.persistence.*; import javax.validation.constraints.NotBlank; @Entity @Table(name = "books") public class Book { @Id @GeneratedValue private Long id; @NotBlank private String book_name; @NotBlank private String author_name; @NotBlank private String isbn; public Book(){ super(); } public Book(Long id, String book_name, String author_name, String isbn) { super(); this.id = id; this.book_name = book_name; this.author_name = author_name; this.isbn=isbn; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getBook_name() { return book_name; } public void setBook_name(String book_name) { this.book_name = book_name; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } }

Aquí estoy usando JPA (API de persistencia de Java) que es una colección de clases y métodos para almacenar datos continuamente en una base de datos.

@Entity : se usa para indicar que esta clase va a ser una Entidad en la base de datos.

@Table - que toma algunos valores como el nombre con el que vas a nombrar tu tabla

@Id — denotes that the id is the primary key / identifying key for this table

@NotBlank — is used to say that these attributes should not be blank.

Other than that there is an empty constructor which has a super method to satisfy the JPA customs. Getter and setter methods are usually in a POJO class (Plain old Java object).

Creating the Repository

Next, we are going to create a repository package to deal with database management in Java.

Create an Interface called BookRepository.java inside the repository package.

package com.rest.API.repository; import com.rest.API.model.Book; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BookRepository extends JpaRepository { }

I have imported the JpaRepository package to use that repository in the BookRepository interface by connecting my most recently coded Book model to do CRUD operations.

There are already built-in methods in those repositories to do CRUD operations.

Eg:

.findAll() - to get All datas .save() - to save the got Data .delete() - to delete the data

Inside the tag we are taking the Model name we are going to use and the Primary key’s datatype.

@Repository: Annotation used to Indicate the DAO (Data Access Object) component in the persistence layer.

It tells the compiler that the interface is going to use the Repository to do database activities.

Creating Controller and Exception Handling

Create a new package called controller, andinside that create a BookController.java file which contains the endpoints.

package com.rest.API.controller; import com.rest.API.exception.BookNotFoundException; import com.rest.API.model.Book; import com.rest.API.repository.BookRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.http.ResponseEntity; import javax.validation.Valid; import java.util.List; @RestController public class BookController { @Autowired BookRepository bookRepository; // Get All Notes @GetMapping("/books") public List getAllNotes() { return bookRepository.findAll(); } // Create a new Note @PostMapping("/books") public Book createNote(@Valid @RequestBody Book book) { return bookRepository.save(book); } // Get a Single Note @GetMapping("/books/{id}") public Book getNoteById(@PathVariable(value = "id") Long bookId) throws BookNotFoundException { return bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); } // Update a Note @PutMapping("/books/{id}") public Book updateNote(@PathVariable(value = "id") Long bookId, @Valid @RequestBody Book bookDetails) throws BookNotFoundException { Book book = bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); book.setBook_name(bookDetails.getBook_name()); book.setAuthor_name(bookDetails.getAuthor_name()); book.setIsbn(bookDetails.getIsbn()); Book updatedBook = bookRepository.save(book); return updatedBook; } // Delete a Note @DeleteMapping("/books/{id}") public ResponseEntity deleteBook(@PathVariable(value = "id") Long bookId) throws BookNotFoundException { Book book = bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); bookRepository.delete(book); return ResponseEntity.ok().build(); } }

The first imported package is for the Book Not Found exception (for which we are going to create a file in a bit).

Explanation of Annotations we used here:

  1. RestController: This annotation is used to denote every method in the annotated class as Domain Object.

So what is Domain Object…?

It simply says that Domain Object == Business Object.

They are usually represented by entities and value objects related to the endpoint we are giving to get the data from the database.

2. Autowired: This annotation is used to wire the bean classes automatically.

For that, you need to know about “What is a bean Class..?

Basically, a Java Bean Class is a simple class which encapsulates many objects into it.

This is an article I wrote on Java Bean Classes.

The following are the Mapping Annotations for the endpoints to perform CRUD Operations.

3. GetMapping: This is an interface which contains the path of the endpoint to perform a Get method. This GetMapping interface uses the RequestMapping interface which can have the “path, value, params, headers” method to perform the Get method in earlier Spring versions.

Now it’s simplified by using GetMapping.

4. PostMapping: This is an interface which contains the path of the endpoint to perform the Post method.

5. PutMapping: This is an interface which contains the path of the endpoint to perform the Put method to Update.

6. DeleteMapping: This is an interface which contains the path of the endpoint to perform the Delete method.

In the final lines, you probably noticed the “ResponseEntity” keyword.

What is that…??

It’s a Java class which inherits HttpEntity class to manipulate the HTTP Responses. Whether the request of the connection is “OK” or if there are any problems, throw an exception from the HttpEntity class.

orElseThrow(): This is a method found in the Optional class in Java8 which was introduced to handle Exceptions. The optional class provides various utility methods to check the presence or absence of an object, which helps to deal with NullPointerException.

orElseThrow is a method that Returns value if present, otherwise invokes an exception.

Creating a NotFoundException if there is no such book_id

As orElseThrow method throws a NotFound Exception. The following is the Exception Handling part. Create a BookNotFoundException.java file inside exception package.

package com.rest.API.exception; public class BookNotFoundException extends Exception { private long book_id; public BookNotFoundException(long book_id) { super(String.format("Book is not found with id : '%s'", book_id)); } }

The created class extends the Superclass of Exception. In the constructor, I’m passing the book_id & prints the exception.

So, that’s it…

We have finished the REST API part. Now you can build the app (which was explained in Part 1) and do some Testings with Postman.

Connecting with MySql Database

Inside the application.properties of your resources folder, add the following:

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring.datasource.url = jdbc:mysql://localhost:3306/library spring.datasource.username = root //normally put your MySQL username spring.datasource.password = YOUR_MYSQL_PASSWORD ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect # Hibernate ddl auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-auto = update

That’s it.

We have built a basic REST API in Spring Boot. Congrats!

If anything is wrong or need to be corrected, please let me know in the comments section.

Get in touch with me on twitter.

Happy Coding!