Tutorial de Dropwizard: Desarrolle servicios web RESTful más rápido

T

¿Qué es Dropwizard?

Dropwizard es un marco Java de código abierto que se utiliza para el desarrollo rápido de servicios web RESTful. O mejor, es el mejor conjunto de herramientas y marcos livianos de su clase para crear servicios web RESTful.

Es bastante fácil de usar, muy fácil de mantener y ha funcionado muy bien en muchos casos diferentes y de acuerdo con la documentación oficial:

“Su objetivo es proporcionar implementaciones confiables y de alto rendimiento de todo lo que necesita una aplicación web lista para producción. Debido a que esta funcionalidad se extrae en una biblioteca reutilizable, su aplicación permanece optimizada y enfocada, reduciendo tanto el tiempo de comercialización como las cargas de mantenimiento”.

Dropwizard permite a un desarrollador construir un proyecto inicial muy rápido, el llamado proyecto de arranque rápido. Esto ayuda a empaquetar la aplicación de una manera que permite instalarla fácilmente en el entorno de producción como un servicio independiente.

Si alguna vez ha estado en la situación de desarrollar un servicio REST en Spring por ejemplo, probablemente sepa lo difícil que puede ser configurar un servicio esqueleto (compararemos los enfoques de Dropwizard y Spring Boot más adelante). Con Dropwizard, es cuestión de agregar literalmente uno de los Maven configuraciones de dependencia.

Aunque Dropwizard no es del agrado de todos, a algunas personas no les gusta usar los componentes y bibliotecas que proporciona, y eso está perfectamente bien.

Componentes predeterminados de Dropwizard

Dropwizard viene con el paquete básico de componentes o bibliotecas necesarios para desarrollar servicios web RESTful, por lo que no necesita incluir y configurar cada uno de ellos por separado:

  • Biblioteca Jetty HTTP: Como sabemos, necesitamos un servidor HTTP para iniciar la aplicación web. Dropwizard utiliza la biblioteca Jetty HTTP para inyectar un servidor HTTP sintonizado directamente en su proyecto. En lugar de implementar sus aplicaciones en un servidor de aplicaciones o servidor web, Dropwizard define un método principal que invoca al servidor Jetty como un proceso independiente. Dropwizard recomienda el uso del servidor Jetty para ejecutar aplicaciones, otros servidores como Tomcat no son compatibles oficialmente.
  • Jersey: es una de las mejores implementaciones de API REST del mercado. Esto le permite crear clases limpias que mapean la solicitud HTTP a objetos java simples. Además, sigue la especificación estándar JAX-RSX y Dropwizard la usa como la herramienta predeterminada para desarrollar aplicaciones web RESTful.
  • Jackson: ciertamente se ha convertido en un estándar cuando se trata de objetos de mapeo de datos hacia y desde JSON. Es una de las mejores API de mapeo de objetos para formato JSON.
  • Métrica: Dropwizard tiene su propia biblioteca, que nos permite leer las métricas de la aplicación a través de puntos finales HTTP.
  • Guayaba: es la biblioteca de utilidades de Google que nos brinda una gran cantidad de clases para acelerar el desarrollo en Java.
  • Volver a iniciar sesión y Slf4j: Estas dos bibliotecas se utilizan para el registro, similar al registro JDK (java.util.logging)
  • Freemarker y Bigote: Elegir un procesador de plantillas es una de las decisiones más importantes. Dropwizard utiliza procesadores conocidos y populares para crear interfaces de usuario.
  • Apache HttpClient: Proporciona la capacidad de interactuar con otros servicios web.
  • Validador de hibernación: Se utiliza para validar la entrada del usuario.
  • Jdbi: Clases de acceso a la base de datos que tienen soporte de Hibernate.
  • Tiempo de joda: Biblioteca para el manejo de fechas y horas.
  • Base líquida: Biblioteca independiente de base de datos de código abierto para rastrear, administrar y aplicar cambios en el esquema de la base de datos.

Estos son algunos de los ingredientes fundamentales si desea hacer un buen servicio de Java RESTful JSON. Dropwizard lo combina muy bien desde una perspectiva de operaciones. La pieza de Métricas es realmente importante porque no solo proporciona métricas, sino que también le alerta si no está implementando las mejores prácticas operativas, como la creación de verificaciones de estado.

Controles de salud se registran como parte de la creación de la aplicación. Si no registra una verificación de estado, la startup le advertirá y se quejará cada vez que inicie. Incluiré esto en un ejemplo más adelante.

Configuración de Maven

Dropwizard es compatible oficialmente con Maven. También puede usar otras herramientas de compilación, aunque la mayoría de las guías y la documentación usan Maven. Maven es una herramienta de gestión de proyectos, basada en el concepto de modelo de objeto de proyecto (POM).

POM.xml contiene toda la información sobre su proyecto (descripción del proyecto, atributos, licencia, versión, lista de dependencias, etc.)

Nosotros definiremos dropwizard.version, antes de agregar las dependencias, en el <properties> etiqueta en nuestro “pom.xml”:

<properties>
  <dropwizard.version>1.3.5</dropwizard.version>
</properties>

Agregue las siguientes dependencias a su pom.xml archivo:

<dependencies>
  <dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-core</artifactId>
    <version>${dropwizard.version}</version>
  </dependency>
</dependencies>

Puede agregar el número de versión directamente en <version> sección por ejemplo:

<version>1.3.5<version>

Después de configurar Maven con éxito, podemos comenzar a hacer nuestra aplicación Dropwizard.

Crear una clase de configuración

Cada aplicación Dropwizard almacena la configuración en YAML archivos. Debemos crear el archivo “config.yml” en el directorio raíz de nuestra aplicación. Este archivo “yml” se deserializará en una instancia del Configuration clase de nuestra aplicación. La clase de configuración de nuestra aplicación es una subclase de la clase de configuración Dropwizard (io.dropwizard.Configuration).

Clase de configuración:

public class DemoConfiguration extends Configuration {

    @NotEmpty
    private String message;
    
    @NotEmpty
    private String firstParameter;
    
    @NotEmpty
    private String secondParameter;
    
    @JsonProperty
    public String getMessage() {
        return message;
    }
    
    @JsonProperty
    public void setMessage(String message) {
        this.message = message;
    }
    
    public String getFirstParameter() {
        return firstParameter;
    }
    
    public void setFirstParameter(String firstParameter) {
        this.firstParameter = firstParameter;
    }
    
    public String getSecondParameter() {
        return secondParameter;
    }
    
    public void setSecondParameter(String secondParameter) {
        this.secondParameter = secondParameter;
    }
}

Ahora, para el archivo “config.yml” en el directorio raíz de nuestra aplicación:

message: Hi %s!, now you will learn about %s from Stack Abuse!
firstParameter: Friend
secondParameter: Dropwizard

los DemoConfiguration La clase se deserializará del archivo YML y los valores de campo se completarán a medida que estén configurados en él.

Crear una clase de aplicación

Ahora debería crearse la clase de aplicación principal. Esta clase recogerá todos los módulos necesarios y preparará nuestro servicio para su uso.

Aquí hay un ejemplo simple de la clase de aplicación:

DemoApplication:

public class DemoApplication extends Application<DemoConfiguration> {

    public static void main(String[] args) throws Exception {
        new DemoApplication().run(new String[] {"server", "config.yml"});
    }
    
    public void run(DemoConfiguration configuration, Environment environment) {
        // code to register module
    }
}

Crear una clase de representación

Ahora deberíamos considerar nuestro servicio de API REST y cómo se representarán los recursos. Necesitamos diseñar el formato JSON y definir la clase de representación adecuada para asegurarnos de que los datos estén en el formato deseado:

{
    "content": "Hi Friend! Now you will learn about Dropwizard from Stack Abuse!"
}

Para lograr este formato, usaremos la siguiente implementación del Representation clase:

Representación:

public class Representation {
    @Length(max = 3)
    private String content;
    
    public Representation() {
        // Jackson deserialization
    }
    
    @JsonProperty
    public String getContent() {
        return content;
    }
    
    public void setContent(String content) {
        this.content = content;
    }
    
    public Representation(String content) {
        this.content = content;
    }
}

Este es un modelo POJO simple. Nuestra clase usa el estándar Java Bean para content propiedad. Esto le permite a Jackson serializarlo en el JSON que necesitamos.

El código de mapeo de objetos de Jackson llenará el campo de contenido del objeto JSON con el valor de retorno de getContent().

Crear una clase de recurso

Los recursos son la esencia de Dropwizard. Los recursos son en realidad las definiciones del URI de punto final de nuestro servicio al que se puede acceder a través del protocolo HTTP. En este ejemplo, crearemos una clase de recurso con un par de anotaciones para mapear solicitudes HTTP.

Dado que Dropwizard usa el JAX-RS implementación, usaremos el @Path anotación para definir la ruta:

DemoResource:

@Path("/v1/resource")
@Produces(MediaType.APPLICATION_JSON)
public class DemoResource {

    private final String message;
    private final String firstParameter;
    private final String secondParameter;
    
    public DemoResource(String message, String firstParameter, String secondParameter) {
        this.message = message;
        this.firstParameter = firstParameter;
        this.secondParameter = secondParameter;
    }
    
    @GET
    @Timed
    public Representation getMessage(@QueryParam("first") Optional<String> first, @QueryParam("second") Optional<String> second) {
        final String value = String.format(message, first.or(firstParameter), second.or(secondParameter));
        return new Representation(value);
    }
}

@Timed se utiliza para registrar automáticamente la duración y la velocidad de sus invocaciones como un temporizador de métricas.

Registro de un recurso

Ahora es necesario registrar la clase anterior en la clase principal de la aplicación. Como se mencionó anteriormente, la clase de aplicación sirve para inicializar nuestro servicio y todos los módulos necesarios, por lo que todos los recursos deben registrarse aquí para ser inicializados con el servicio.

En la clase de aplicación principal, agregue lo siguiente:

@Override
public void run(DemoConfiguration configuration, Environment environment) {
    final DemoResource resource = new DemoResource(configuration.getMessage(),
            configuration.getFirstParameter(), configuration.getSecondParameter());
    environment.jersey().register(resource);
}

Creación de una aplicación Dropwizard

Es una buena idea crear un FAT JAR que contendrá todos los archivos “.class” necesarios para ejecutar la aplicación. Este JAR se puede implementar en un entorno diferente desde la prueba hasta la producción sin ningún cambio.

Para hacer nuestro JAR necesitamos configurar el plugin Maven maven-shade. La siguiente configuración debe agregarse a nuestro “pom.xml”, debajo del dependencies sección:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer 
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                                    <mainClass>com.dropwizard.DemoApplication</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Ejecutando su aplicación

Ahora deberíamos poder lanzar nuestra aplicación. Si ha creado correctamente su JAR, puede ejecutarlo desde la línea de comandos:

$ java –jar target/dropwizard-demo-1.0.SNAPSHOT.jar server config.yml

o directamente desde su IDE – ejecutando el DemoApplication clase principal:

Si todo comenzó correctamente, debería aparecer algo como esto:

Ahora, su aplicación Dropwizard está escuchando en el puerto 8080 para solicitudes de aplicaciones y en el puerto 8081 para solicitudes de administración. Notarás que usamos los argumentos server y config.yml para ejecutar el servicio, indicándole al servidor qué archivo de configuración utilizar.

Esto también se puede hacer en el main método de DemoApplication clase, como en el ejemplo anterior.

Puede acceder a su aplicación en http://localhost:8080/v1/resource o con parámetros http://localhost:8080/v1/resource?first=John&second=everything.

Debería recibir un mensaje con o sin parámetros de reenvío, según su llamada.

Cambiar la ruta del contexto

De forma predeterminada, la aplicación Dropwizard ejecutará sus puntos finales en /path. Por lo tanto, si no menciona ninguna ruta de contexto para su aplicación, se supone que se puede acceder a la aplicación en http://localhost:8080. Sin embargo, si desea cambiar esto, puede configurar una ruta diferente agregando lo siguiente a su archivo YML:

server:
    applicationContextPath: /application

Agregar una verificación de estado

Con respecto a la declaración anterior sobre el marco de métricas que hace cumplir las verificaciones de estado:

Las comprobaciones de estado son simplemente puntos finales HTTP que iteran sobre varios enlaces que usted crea. Si bien algunos ceden a la tentación de devolver un control de estado que siempre devuelve un estado “saludable”, siempre que el servicio esté funcionando, esta es una práctica realmente mala.

Las comprobaciones de estado deben usarse para mejorar el código, por ejemplo: si tiene una base de datos, debe poder proporcionar una conexión a la base de datos. Ponga una verificación de estado allí, asegúrese de que la base de datos no tenga demasiadas conexiones de cliente, o ningún subproceso bloqueado, etc.

Vamos a crear nuestro HealthCheck clase:

DemoHealthCheck:

Por el bien del tutorial, mantendremos esto simple. En entornos de trabajo, estas verificaciones se verían diferentes, pero en su mayoría giran en torno a casos de verificación, similares a esto:

public class DemoHealthCheck extends HealthCheck {

    @Override
    protected Result check() throws Exception {
        final String field = "Dropwizard";
        if (field.equalsIgnoreCase("Dropwizard")) {
            return Result.healthy();
        }
        return Result.unhealthy("Error, not Healthy!");
    }
}

Como antes, ahora registramos nuestro HealthCheck class en la clase principal de la aplicación.

DemoApplication:

@Override
public void run(DemoConfiguration configuration, Environment environment) {
    final DemoResource resource = new DemoResource(configuration.getMessage(),
            configuration.getFirstParameter(), configuration.getSecondParameter());
    final DemoHealthCheck healthCheck = new DemoHealthCheck();
    environment.healthChecks().register("Dropwizard", healthCheck);
    environment.jersey().register(resource);
}

Ahora, cuando inicie su aplicación, la salida del registro de su consola no se quejará de las verificaciones de estado.

Diferencias entre los enfoques Dropwizard y Spring Boot

Ambos son realmente fáciles de aprender y comenzar a trabajar pocas horas después de escribir su primera solicitud.

/ Bota de Spring Dropwizard

HTTPEmbarcaderoGato
DESCANSOJerseyResorte, JAX-RS
JSONJacksonJackson, GSON, json-simple
MétricaMétricas de DropwizardSpring
Comprobaciones de estadoDropwizardSpring
Inicio sesiónLogback, slf4jLogback, Log4j, slf4j, Apache commong-logging
Pruebasdropwizard-testing (Junit, Mockito)prueba de arranque de arranque de Spring (JUnit, Mockito)
Integraciones oficialesValidador de Hibernate, Guava, Apache HttpClient, cliente de Jersey, JDBI, Liquibase, Moustache, Freemaker, Joda time40+ Starter POM oficiales para cualquier propósito

Conclusión

Con nuestra aplicación en funcionamiento, podemos dar algunas notas clave sobre el uso de Dropwizard para desarrollar servicios web RESTful.

Dropwizard se centra en la producción, es fácil de usar, simple de implementar, simple de monitorear, desarrollar y configurar un marco REST de alto rendimiento.

Quizás una de las mayores ventajas es que ofrece una configuración de arranque increíblemente rápida para su proyecto. Con un conjunto de herramientas y bibliotecas incluido para satisfacer las necesidades de la mayoría de los desarrolladores, no tiene que preocuparse por agregar y configurar cada una de ellas por separado.

Algunas desventajas serían que está restringido al uso de lo que Dropwizard ofrece o admite (perdiendo libertad), pero también agregar demasiadas bibliotecas de terceros puede causar una complejidad innecesaria en el desarrollo.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad