Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Java / Microservicio REST Java con Spark – Parte 1

Microservicio REST Java con Spark – Parte 1

Por jc mouse jueves, julio 12, 2018

En este y un segundo post desarrollaremos un microservicio java utilizando el framework Spark que implementara las funciones básicas CRUD (Crear, Leer, Actualizar y Borrar)  sin base de datos para gestionar en memoria registros de una lista de personas. Paralelamente a la escritura del código, iremos probando este servicio en un cliente REST como es Imsomnia.

Herramientas:

  • Java 8
  • Framework Spark [Introducción a Spark] [sparkjava.com]
  • Maven (instalado y configurado)
  • IDE Netbeans 8.x
  • Cliente REST Imsomnia (Si conoces de otro igual sirve)
  • Teoría básica sobre la Arquitectura REST
  • Base de Datos: No

Nivel: Intermedio-Avanzado

Paso 1: El Proyecto Java

Clic en menú New Project -> Seleccionar categoría Maven -> Tipo de proyecto Java Application, [siguiente] para continuar.

A continuación, (1) Ingresa un nombre para el proyecto «SparkREST» sin espacios, (2) completa la información a tu gusto o deja como esta (3) para crear el proyecto, clic en [terminar]

microservice netbeans

Paso 2: Dependencias

En este paso debemos agregar las dependencias para proyecto, solo son 2 en realidad, el microframework Spark y la librería Google GSON para el trabajo con objetos JSON.

Para agregar dependencias al proyecto, clic sobre la carpeta «dependencias» -> agregar dependencias

Para Spark la configuración es la siguiente:

core_maven

Y para GSON es:

gson maven

Si es la primera que usas estas librerías, clic derecho sobre «dependencias» -> descargar dependencias declaradas y esperar a que las librerías se descarguen en tu repositorio local.

Paso 3.  Las clases

Dado el tamaño del proyecto nos daremos la libertad de crear las clases en un solo paquete como es example.org.sparkrest, las clases son:

  • Clase principal Main.java
  • Persona.java
  • Respuesta.java
  • Servicio.java

Iremos explicando la función de cada clase paso a paso, mientras tu proyecto debe tener el siguiente aspecto:

microframework java

Paso 4. Clase Persona y clase Respuesta

Las siguientes clases no sufrirán más cambios en el desarrollo de todo el proyecto, razón por la cual, las declararemos ahora.

Clase Persona: Esta clase nos permite almacenar la información que se intercambiara entre el cliente y el microservicio y consta de 3 atributos, DNI (String), nombre (String) y edad (Int).

 1 package example.org.sparkrest;
 2 /**
 3  * @see https://www.jc-mouse.net/
 4  * @author mouse
 5  */
 6 public class Persona {
 7 
 8     private String dni;
 9     private String nombre;
10     private int edad;
11 
12     public Persona() {}
13 
14     public Persona(String dni, String nombre, int edad) {
15         this.dni = dni;
16         this.nombre = nombre;
17         this.edad = edad;
18     }
19 
20     public String getDni() {
21         return dni;
22     }
23 
24     public void setDni(String dni) {
25         this.dni = dni;
26     }
27 
28     public String getNombre() {
29         return nombre;
30     }
31 
32     public void setNombre(String nombre) {
33         this.nombre = nombre;
34     }
35 
36     public int getEdad() {
37         return edad;
38     }
39 
40     public void setEdad(int edad) {
41         this.edad = edad;
42     }
43     
44 }

Clase Respuesta: Esta clase nos permitirá definir una respuesta para el cliente según sea el caso y el código es el siguiente:

 1 package example.org.sparkrest;
 2 /**
 3  * @see https://www.jc-mouse.net/
 4  * @author mouse
 5  */
 6 public class Respuesta {
 7 
 8     private String mensaje;
 9 
10     public Respuesta(String mensaje) {
11         this.mensaje = mensaje;
12     }
13 
14     public String getMensaje() {
15         return mensaje;
16     }
17 
18     public void setMensaje(String mensaje) {
19         this.mensaje = mensaje;
20     }
21 
22 }

Estas dos clases conformaran nuestro modelo de datos.

Paso 5. El Servicio

En este proyecto no se hará uso de una base de datos como dijimos en un principio esto con el fin de hacer este tutorial más sencillo y corto, sin embargo es necesario una clase que gestione las operaciones sobre los datos que en este caso serán almacenados en memoria. La clase se llama Servicio.java y cuentas con los métodos necesarios para realizar el CRUD (Crear, Leer, Actualizar y Borrar)  sobre la capa de persistencia del sistema.

package example.org.sparkrest;
import java.util.ArrayList;
import java.util.List;
/**
 * Clase que emula las operaciones basicas CRUD sobre una base de datos
 * 
 * @see https://www.jc-mouse.net/
 * @author mouse
 */
public class Servicio {

    /**
     * Para almacenar los datos del servicio
     */
    private List<Persona> personaList;

    /**
     * Constructor de clase
     */
    public Servicio() {
        personaList = new ArrayList<>();
        //creamos 2 datos de ejemplo
        personaList.add(new Persona("123", "Armando Bronca", 20));
        personaList.add(new Persona("456", "Tula Traes", 28));
    }

    /**
     * Realiza una busqueda en la base de datos y retorna los mismos en un array
     *
     * @return List
     */
    public List<Persona> buscarTodo() {
        return personaList;
    }

    /**
     * Realiza una busqueda en la base de datos de un registro dado su ID
     *
     * @param dni ID unico del registro
     * @return Persona Si el registro no existe retorna NULL
     */
    public Persona buscar(String dni) {
        for (Persona p : personaList) {
            if (p.getDni().equals(dni)) {
                return p;
            }
        }
        return null;
    }

    /**
     * Registra a una nueva persona en la base de datos
     *
     * @param persona
     * @return boolean TRUE si el registro tuvo exito, FALSE en caso contrario
     */
    public boolean agregar(Persona persona) {
        personaList.add(persona);
        return true;
    }

    /**
     * Actualiza el registro de una persona
     * 
     * @param persona
     * @return boolean TRUE si la acción tuvo exito, FALSE en caso contrario
     */
    public boolean actualizar(Persona persona) {
        for (int i = 0; i < personaList.size(); i++) {
            if (personaList.get(i).getDni().equals(persona.getDni())) {
                personaList.set(i, persona);
                return true;
            }
        }
        return false;
    }

    /**
     * Elimina un registro dado su DNI
     * 
     * @param dni
     * @return boolean TRUE si la acción tuvo exito, FALSE en caso contrario
     */
    public boolean eliminar(String dni) {
        for (Persona p : personaList) {
            if (p.getDni().equals(dni)) {
                personaList.remove(p);
                return true;
            }
        }
        return false;
    }

}

Paso 6. Clase Main

A partir de este punto iremos implementando paso a paso el código necesario para los métodos HTTP como son GET (lectura y consulta), POST (creación), PUT (edición) y DELETE (eliminación). Así mismo iremos testeando paralelamente el código con el Cliente Rest Imsomnia.

Entonces abrimos la clase Main.java y…

Paso 6.1 Librerías

Agregamos los siguientes import a la clase Main:

import java.util.List;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
// Spark
import static spark.Spark.after;
import static spark.Spark.delete;
import static spark.Spark.get;
import static spark.Spark.notFound;
import static spark.Spark.post;
import static spark.Spark.put;

Paso 6.2 after y notFound

Antes de implementar el CRUD, debemos implementar instancias a nuestra clase Servicio (3) y a la librería Google GSON (7).

Utilizamos el filtro after para modificar el tipo de respuesta al cliente, que en nuestro caso queremos que sea de tipo JSON. En nuestro ejemplo solo utilizaremos JSON razón por la cual definimos este tipo para todo la aplicación, pero se debe tener en cuenta que los tipos devueltos por el servicio pueden ser html, json, imágenes, etc.

notFound nos sirve para manejar las rutas a la API que no estén establecidas para nuestro servicio, en este caso responderemos con un código 404 y un mensaje de alerta.

 1 public class Main {
 2 
 3     private static Servicio servicio = new Servicio();
 4 
 5     public static void main(String[] args) {
 6 
 7         Gson gson = new Gson();
 8 
 9         /**
10          * El tipo de contenido de respuesta para todos las solicitudes sera
11          * JSON
12          */
13         after((request, response) -> {
14             response.type("application/json");
15         });
16 
17         /**
18          * Mensaje de respuesta para solicitudes que no existan en la API
19          */
20         notFound((request, response) -> {
21             response.status(404);
22             return gson.toJson(new Respuesta("El recursos que trata de acceder NO EXISTE!!!"));
23         });        
24         
25     }
26 
27 }

Guardamos los cambios y ejecutamos nuestro servicio.

Abrimos nuestro Cliente REST Insomnia y creamos un nuevo espacio de trabajo.

A continuación agregamos una nueva solicitud que llamaremos «Error 404» de tipo GET. Escribimos una solicitud que sabemos no existe «http://localhost:4567/autos/777» (1) presionamos SEND (2), obtenemos una respuesta «404 Not Found» y un mensaje en formato JSON «El recursos que trata de acceder NO EXISTE!!!«.

Si presionamos la pestaña Header (4), observaremos que el Content-type es de tipo application/json como definimos en el código, intenta comentar esa linea de código en el after y vuelve a realizar este proceso, obtendrás ahora que el Content-Type es de tipo text/html;charset=utf-8

http code 404

Paso 6.3 GET

Después del notFound, agregamos el código para el GET, dos en en realidad, uno para obtener la lista completa de personas (sin parámetros) y otro GET para buscar el registro de una persona dado su ID (en nuestro caso el DNI de usuario).

 1 /**
 2  * retorna lista completa de personas
 3  */
 4 get("/personas", (request, response)
 5   -> {
 6     response.status(200);//Codigo de respuesta
 7     List result = servicio.buscarTodo();//obtiene lista de personas
 8     return result;
 9 }, gson::toJson);
10 
11 /**
12  * retorna registro de una persona si existe, sino retorna mensaje
13  */
14 get("/personas/:id", (request, response)
15   -> {
16     Persona persona = servicio.buscar(request.params(":id"));
17     if (persona != null) {//registro existe
18        response.status(200);
19        return persona;
20     } else {//registro no existe
21        response.status(404); // 404 Not found
22        return new Respuesta("Usuario no encontrado");
23     }
24 }, gson::toJson);

GET nos sirve para obtener información del servidor que puede ser de casi cualquier tipo (html, xml, json, imagen, etc) para nuestro ejemplo tenemos establecido que solo retorne objetos JSON.

En Imsomnia creamos una nueva solicitud «Listar Personas» de tipo GET y escribimos «http://localhost:4567/personas» esto le dice al servicio que utilice el primer get sin parámetros, nuestro resultado es el siguiente:

200 code ok

Si no contáramos con datos, nos retornaría un array vacío [ ].

De la misma forma creamos una nueva solicitud de tipo GET con el nombre de «Buscar persona«, escribe «http://localhost:4567/personas/123» y presiona SEND

search rest api

Si el ID que pasamos como parámetro NO EXISTE pues nos mostrara un código 404 y un mensaje como el siguiente:

user not found

Eso es todo por el momento, en un siguiente post finalizamos nuestro microservicio implementando el código para los métodos POST, PUT y DELETE

Actualizado

Segunda parte disponible >>Aquí viejo<<

enjoy!!!

Tags

Artículos similares

Crea patrón de desbloqueo para tus app java

El patrón de desbloqueo es una medida de seguridad que tienen algunos teléfonos inteligentes para evitar el acceso al di[...]

Texto e Imagen en Java2d (Proyecto)

Nivel: Intermedio-Avanzado IDE: Netbeans 6.9 o Sup. Tiempo: 30 minutos En este tutorial crearemos una aplicación que nos[...]

Tabla para inventarios de Entradas y Salidas

A veces navegando en la internet buscando novedades , investigando o simplemente perdiendo el tiempo 🙂 se encuentran cos[...]

WebServices – El Cliente

En un tutorial anterior se creo un WebServices [Java WebServices] utilizando java y Netbeans, en esta ocasión se da cont[...]

Formateo de registros en Excel con JExcel

Tenia un problema, me pasaron unos archivos excel con unos cientos de registros (ver imagen más abajo) que exportaron de[...]

Manipular colecciones de una forma sencilla

Java proporciona Collection Framework, que define varias clases e interfaces para representar un grupo de objetos como u[...]