Java Quarkus: API REST H2

Ejemplo Api REST con ORM Panache y base de datos H2

El framework Java Quarkus proporciona una serie de características que facilitan mucho la creación y el mantenimiento de una API REST, entre ellas compatibilidad con el estandar OpenApi e integración con entornos de microservicios.

Comando Maven para generar el aplicativo java:

mvn io.quarkus.platform:quarkus-maven-plugin:2.2.3.Final:create \
-DprojectGroupId=dev.failapp \
-DprojectArtifactId=rest-lab \
-DclassName="dev.failapp.lab.resource.PersonRest" \
-Dpath="/api/v1/lab"

En el archivo 'pom.xml' se definen las dependencias para servicios REST Json, ORM Panache y el driver de base de datos (en este caso H2):

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-h2</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm-panache</artifactId>
    </dependency>

Agregamos una clase entidad sencilla y una clase 'repositorio' para temas de persistencia:

@Entity
@Table(name = "persons")
public class Person {

    @Id
    @GeneratedValue
    private Long id;
    private String documentId;
    private String firstName;
    private String lastName;
    private Integer age;

    public Person() {
    }

    // getters ..
    // setters ..
}
@ApplicationScoped
public class PersonRepository implements PanacheRepository<Person> {

    public Optional<Person> findByDocumentId(String documentId) {
        return find("documentId", documentId).firstResultOptional();
    }
}

La clase encargada de implementar el servicio tiene el siguiente aspecto:


@ApplicationScoped
public class PersonService {

    private static final Logger log = Logger.getLogger(PersonService.class);

    @Inject
    private PersonRepository personRepository;

    public long countPersons() {
        return personRepository.count();
    }

    public List<Person> fetchPersons(int page) {
        int perPage = 50;
        page = page -1;
        PanacheQuery<Person> persons = personRepository.findAll(Sort.ascending("id"));
        persons.page(Page.ofSize(perPage));
        return persons.page( Page.of(page, perPage) ).list();
    }

    public Optional<Person> fetchPerson(String documentId) {
        if (Optional.ofNullable(documentId).isEmpty()) return Optional.empty();
        return personRepository.findByDocumentId(documentId.strip());
    }
}

La clase con el Endpoint que consume el servicio luce de la siguiente forma:

@Path("/")
public class PersonRest {

    @Inject
    private PersonService personService;

    @GET
    public Response index() {
        return Response.status(Response.Status.NOT_FOUND)
                .build();
    }

    @GET
    @Path("/api/v1/lab/persons")
    public List<Person> list(@QueryParam Integer page) {
        if (Optional.ofNullable(page).isEmpty()) page=1;
        return personService.fetchPersons(page);
    }

    @GET
    @Path("/api/v1/lab/persons/{documentId}")
    public Response findByDocumentId(@PathParam String documentId) {

        Optional<Person> person = personService.fetchPerson(documentId);
        if (person.isPresent())
            return Response.ok(person.get()).build();

        return Response.status(Response.Status.NOT_FOUND).build();
    }

    @POST
    @Path("/api/v1/lab/persons")
    public Response save(Person person) {

        Optional<Person> _person = personService.storePerson(person);
        if (_person.isPresent())
            return Response.ok(_person.get()).build();

        return Response.status(Response.Status.NOT_FOUND).build();
    }


    @DELETE
    @Path("/api/v1/lab/persons/{documentId}")
    public Response deleteByDocumentId(@PathParam String documentId) {

        boolean delete = personService.deletePerson(documentId);
        if (delete)
            return Response.ok().build();

        return Response.status(Response.Status.NOT_FOUND).build();
    }

    @GET
    @Path("/api/v1/lab/persons/count")
    public long count() {
        return personService.countPersons();
    }

}

Puedes descargar el código fuente completo de este ejemplo en el siguiente enlace.




¿Tienes alguna consulta?
Puedes contactarme enviándome un mensaje desde aquí.