Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Java / Microservicio REST Java con Spark – Parte 1

Microservicio REST Java con Spark – Parte 1

Autor 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 http://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 http://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 http://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

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Material Design: Notificaciones (Snackbar)

Material Design: Notificaciones (Snackbar)

Material Design introduce una nueva forma de mostrar notificaciones al usuario, estos son los snackbar, similares a los...

Creación y uso de parametros en Jaspersoft Studio

Creación y uso de parametros en Jaspersoft Studio

Hola 🙂 En este video tutorial veremos como crear y usar parámetros en reportes con JasperSoft Studio, la base de datos q...

Agregar tablas a los items de un JComboBox

Agregar tablas a los items de un JComboBox

En este post personalizaremos un componente JComboBox para que sus elementos acepten tablas (JTable) en lugar de texto s...

Libreria swing BlackTabbedPane

Libreria swing BlackTabbedPane

Continuación del tutorial [Personalizar JTabbedPane con Netbeans]. La clase BlackTabbedPaneUI que extendemos de BasicTab...

Agregar JComboBox a un JTable

Agregar JComboBox a un JTable

En este post, crearemos una tabla swing que implemente un control jcombobox en una columna de una tabla, llenaremos con...

Métodos Numéricos: Sustitución Directa

Métodos Numéricos: Sustitución Directa

El Método de Sustitución Directa básicamente consiste en asumir un valor, reemplazar el mismo en la función despejada y...

Comparte lo que sabes

Categorias

Últimas entradas

Sans Forgetica es una fuente diseñada utilizando los principios de la psicología cognitiva para ayudar a recordar mejor...

Facebook la compañía de Mark Zuckerberg confirmó hace unas semanas que la Red Social había sido hackeado debido a una br...

Google+ o Google plus como también se le conoce a la red social del gigante de la informática Google cerrará para siempr...

Como dice un viejo dicho, “La practica hace al maestro” y en el mundo de la programación no es diferente, po...

Android Bolivia

MAUS