Ejemplo de API REST en Java con JAX-RS y Spring Boot

Escrito por el .
blog-stack java planeta-codigo programacion spring
Comentarios

Java
Spring Framework

En Java a través de JAX-RS, una de entre las varias especificaciones de JavaEE, podemos desarrollar servicios web basados en REST y JSON. Estos servicios web al usar la infraestructura de la web y el protocolo HTTP podemos hacer uso de facilidades que proporciona como cacheo, protocolo seguro, HTTP/2, compresión o autenticación. Usando Spring Boot podemos desarrollar servicios web autocontenidos al igual que podemos hacer con las aplicaciones web tradicionales.

Para facilitar el inicio de los proyectos podemos usar Spring Initializr seleccionando los módulos web y JAX-RS con la implementación de referencia Jersey. Al proyecto creado deberemos añadir los servicios que queramos proporcionar. En el ejemplo añadiré uno muy sencillo que devuelva un nuevo mensaje creado en un servicio inyectado en la clase del recurso del servicio REST.

Esta es la definición del bean del servicio que creará el mensaje para el contenedor de inversión de control, también definimos el recurso del servicio REST para Jersey.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package io.github.picodotdev.blogbitix.springbootjaxrs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Main {

    @Bean
    MessageService buillMessageService() {
        return new DefaultMessageService();
    }

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package io.github.picodotdev.blogbitix.springbootjaxrs;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(MessageResource.class);
    }

}

El servicio lo definimos en una interfaz y una clase que la implementa.

1
2
3
4
5
6
package io.github.picodotdev.blogbitix.springbootjaxrs;

public interface MessageService {

    Message create(String message);
}
1
2
3
4
5
6
7
8
9
package io.github.picodotdev.blogbitix.springbootjaxrs;

public class DefaultMessageService implements MessageService {

    @Override
    public Message create(String message) {
        return new Message(message);
    }
}
 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
package io.github.picodotdev.blogbitix.springbootjaxrs;

import java.util.Date;

public class Message {

    private String message;
    private Date date;

    public Message(String message) {
        this.message = message;
        this.date = new Date();
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

Es habitual que los servicios REST produzca como resultado un JSON como formato para devolver los datos. No necesitaremos hacer nada especial para convertir el Java Bean de la clase Message a JSON, de ello se encargará automáticamente JAX-RS. Con anotaciones como @QueryParam podemos obtener los parámetros del query string, de la URL o cabeceras enviadas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package io.github.picodotdev.blogbitix.springbootjaxrs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

@Component
@Path("/message")
public class MessageResource {

    @Autowired
    private MessageService messageService;

    @GET
    @Produces("application/json")
    public Message message(@QueryParam("message") String message) {
        return messageService.create(message);
    }

}

Iniciada la aplicación con ./gradlew run y con la siguiente comando de curl y URL obtendremos el mensaje en formato JSON en la salida.

1
$ curl -v http://localhost:8080/message?message=Hola
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /message?message=Hola HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.50.1
> Accept: */*
> 
< HTTP/1.1 200 
< Content-Type: application/json
< Content-Length: 39
< Date: Sat, 17 Sep 2016 09:55:29 GMT
< 
* Connection #0 to host localhost left intact
{"message":"Hola","date":1474106129856}

Al diseñar APIs REST más complejas que este sencillo ejemplo conviene conocer el término HATEOAS. Deberemos definir como organizar la información devuelta por los diferentes que los libros RESTful Web APIs y REST in Practice además de artículos con consejos sobre como diseñar APIs RESTful.

Una vez que disponemos del servicio REST podemos añadir autenticación y autorización con Keycloak como proveedor de OAuth.

Otra alternativa a una interfaz REST es usar GraphQL que muestro en el artículo Ejemplo de GraphQL para una interfaz de un servicio con Spring Boot y Java

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew run.