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

GridView con imagenes en miniatura

GridView con imagenes en miniatura

Entre las muchas aplicaciones que hay en la playstore de google están las galerías de fotos de chicas 🙂 que tantos nos e...

Tutorial HeidiSQL: Sesion, Base de datos y Tablas

Tutorial HeidiSQL: Sesion, Base de datos y Tablas

HeidiSQL es un software libre y de código abierto que permite conectarse a servidores MySQL, MariaDB, Percona Server, Mi...

Personaliza un JComboBox estilo Metro de Windows

Personaliza un JComboBox estilo Metro de Windows

Si bien se pueden encontrar en google estilos java (Look and Feel) listos para cambiar la apariencia de nuestras aplicac...

ArrayDeque: Cola doblemente terminada

ArrayDeque: Cola doblemente terminada

Una cola doblemente terminada o deque es una estructura de datos lineal que permite insertar y eliminar elementos por am...

ANSI: Colorear consola de salida de Netbeans

ANSI: Colorear consola de salida de Netbeans

Cuando realizamos proyectos java desde Netbeans, usamos System.out.println para imprimir datos en consola (para depurar,...

Animación de JProgressBar con hilos

Animación de JProgressBar con hilos

Si nuestra aplicación tiene que llevar a cabo un cierto trabajo que no sabemos cuanto durará y que a la vez consume much...

Comparte lo que sabes

Categorias

Últimas entradas

Blockly proyecto de Google for Education, es una biblioteca en JavaScript que agrega un editor de código visual a aplica...

j2html es una biblioteca para java que permite generar código html seguro desde código java utilizando sus propias etiqu...

En este post haremos uso de PanoramaImageView para agregar a una aplicación android, una vista panorámica de 180° y 360°...

¿Que es una infografia? “Una infografía es una representación visual informativa o diagrama de textos escritos que...

Android Bolivia

MAUS