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

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 de su clase de peso ligero y...

¿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 de trabajo ligeros de su clase para crear servicios web RESTful.

Es bastante fácil de usar, muy fácil de mantener y ha funcionado extremadamente bien en muchos casos diferentes y según la [documentación oficial] (https://www.dropwizard.io/1.3.5/docs/getting-started. HTML):

"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 se mantiene ágil y enfocada, lo que reduce tanto el tiempo de comercialización como las cargas de mantenimiento. "

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

Si alguna vez se ha visto en la situación de desarrollar un servicio REST en Primavera, por ejemplo, probablemente sepa lo difícil que puede ser configurar un servicio básico (lo haremos compare los enfoques de Dropwizard y Spring Boot más adelante). Con Dropwizard, se trata de agregar literalmente una de las configuraciones de dependencia Experto.

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

Componentes de Dropwizard predeterminados

Dropwizard viene con el paquete básico de componentes o bibliotecas necesarias 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 usa la biblioteca Jetty HTTP para inyectar un servidor HTTP ajustado directamente en su proyecto. En lugar de implementar sus aplicaciones en un servidor de aplicaciones o un servidor web, Dropwizard define un método principal que invoca el servidor Jetty como un proceso independiente. Dropwizard recomienda el uso del servidor Jetty para ejecutar aplicaciones, otros servidores como Tomcat no son oficialmente compatibles.

  • Jersey: es una de las mejores implementaciones de API REST del mercado. Esto le permite crear clases limpias que asignan solicitudes HTTP a objetos Java simples. Además, sigue la especificación JAX-RSX estándar 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.

  • [Metrics]{rel=“nofollow” target="_blank"}: 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 usan para iniciar sesión, similar a JDK logging (java .util.registro)

  • marcador libre 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.

  • Cliente Http de Apache: Brinda la posibilidad de interactuar con otros servicios web.

  • Validador de Hibernate: Se utiliza para validar la entrada del usuario.

  • Jdbi: clases de acceso a la base de datos que tienen soporte para Hibernate.

  • hora joda: Biblioteca para el manejo de fechas y horas.

  • base liquida: Biblioteca independiente de la 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 principales si desea crear un buen JSON RESTful que sirva el servicio Java. Dropwizard lo combina muy bien desde la perspectiva de las operaciones. La pieza de Métricas es realmente importante porque no solo proporciona métricas, sino que también lo alerta si no está implementando las mejores prácticas operativas, como la creación de controles de salud.

Los controles de estado se registran como parte de la creación de la aplicación. Si no registra un control de salud, el inicio le avisará y se quejará cada vez que inicie. Incluiré esto en un ejemplo más adelante.

Configuración de Maven {#configuración de Maven}

Dropwizard admite oficialmente 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.)

Definiremos dropwizard.version, antes de agregar las dependencias, en la etiqueta <properties> en nuestro "pom.xml":

1
2
3
<properties>
  <dropwizard.version>1.3.5</dropwizard.version>
</properties>

Agregue las siguientes dependencias a su archivo pom.xml:

1
2
3
4
5
6
7
<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 la sección <versión>, por ejemplo:

1
<version>1.3.5<version>

Luego de configurar correctamente Maven, podemos comenzar a crear nuestra aplicación Dropwizard.

Creación de una clase de configuración

Cada aplicación de Dropwizard almacena la configuración en archivos YAML. Debemos crear el archivo "config.yml" en el directorio raíz de nuestra aplicación. Este archivo "yml" se deserializará a una instancia de la clase Configuración 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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:

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

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

Creación de una clase de aplicación {#creación de una clase de aplicación}

Ahora se debe crear 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:

Aplicación de demostración:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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
    }
}

Creación de una clase de representación

Ahora debemos considerar nuestro servicio 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 garantizar que los datos estén en el formato deseado:

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

Para lograr este formato, utilizaremos la siguiente implementación de la clase Representación:

Representación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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 la propiedad content. Esto le permite a Jackson serializarlo en el JSON que necesitamos.

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

Creación de una clase de recursos

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.

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

Recurso de demostración:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@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 usa para registrar automáticamente la duración y el índice 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 inicializarse con el servicio.

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

1
2
3
4
5
6
@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 el llamado FAT JAR que contendrá todos los archivos ".class" necesarios para ejecutar la aplicación. Este JAR se puede implementar en diferentes entornos desde la prueba hasta la producción sin ningún cambio.

Para hacer nuestro JAR necesitamos configurar el complemento Maven maven-shade. La siguiente configuración debe agregarse a nuestro "pom.xml", en la sección dependencias:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    <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 iniciar nuestra aplicación. Si ha creado correctamente su JAR, puede ejecutarlo desde la línea de comandos:

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

o directamente desde su IDE, ejecutando la clase principal DemoApplication:

mainClass{.img-responsive}

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

outputLog{.img-responsive}

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á que usamos los argumentos servidor y config.yml para ejecutar el servicio, diciéndole al servidor qué archivo de configuración usar.

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

Puede acceder a su aplicación en http://localhost:8080/v1/resource o con los 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.

Cambiando la ruta de contexto

De forma predeterminada, la aplicación Dropwizard ejecutará sus puntos finales en /ruta. 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:

1
2
server:
    applicationContextPath: /application

Adición de una comprobación de estado

Con respecto a la declaración anterior sobre el marco de Metrics que hace cumplir los controles de salud:

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

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 un control de salud allí, asegúrese de que la base de datos no tenga demasiadas conexiones de clientes, o ningún bloqueo de subprocesos, etc.

Vamos a crear nuestra clase HealthCheck:

Demostración HealthCheck:

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, similar a esto:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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 nuestra clase HealthCheck en la clase principal de la aplicación.

Aplicación de demostración:

1
2
3
4
5
6
7
8
@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 comprobaciones de estado.

Diferencias entre los enfoques de Dropwizard y Spring Boot {#diferencias entre los enfoques de Dropwizard y Spring Boot}

Ambos son realmente fáciles de aprender y comenzar a las pocas horas de escribir su primera aplicación.

/ Bota Primavera Dropwizard


Tomcat de embarcadero HTTP Resorte de jersey REST, JAX-RS JSON Jackson Jackson, GSON, json-simple Métricas Dropwizard métricas Spring Comprobaciones de salud Dropwizard Spring Registro Logback, slf4j Logback, Log4j, slf4j, Apache commong-logging Prueba dropwizard-testing (Junit, Mockito) spring-boot-starter-test (JUnit, Mockito) Integraciones oficiales Validador de Hibernate, Guava, Apache HttpClient, cliente de Jersey, JDBI, Liquibase, Moustache, Freemaker, Joda time 40+ POM de inicio oficial 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 incluido de herramientas y bibliotecas para satisfacer las necesidades de la mayoría de los desarrolladores, no tiene que preocuparse por agregar y configurar cada uno de ellos por separado.

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

Licensed under CC BY-NC-SA 4.0