Creating a CRUD app with Quarkus, Reactive Hibernate, Panache and GraphQL using a PostgreSQL database

David
Geek Culture
Published in
4 min readJun 7, 2021

--

This guide demonstrates how your Quarkus application can use SmallRye GraphQL, an implementation of the MicroProfile GraphQL specification together with the reactive the Hibernate Panache extension together with a PostgreSQL database. It presents in short a set of movies and actors with their corresponding relations and mutational operations.

quarkus.io

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

GraphQL was originally developed by Facebook in 2012 and has been an open standard since 2015.

GraphQL is not a replacement for REST API specification but merely an alternative. Unlike REST, GraphQL API’s have the ability to benefit the client by:

Preventing Over-fetching and Under-fetching

REST API’s are server-driven fixed data responses that cannot be determined by the client. Although the client does not require all the fields the client must retrieve all the data hence Over-fetching. A client may also require multiple REST API calls according to the first call (HATEOAS) to retrieve all the data that is required thereby Under-fetching.

API Evolution

Since GraphQL API’s returns data that are requested by the client adding additional fields and capabilities to existing API will not create breaking changes to existing clients.

With this in mind we can have a lot of different flexible approaches when designing our entities and make our queries more loosely coupled. GraphQL driven design also facilitates the problematic issues around n + 1 selects to the database.

Prerequisites

  • PostgreSQL ≥ 10.5 (in Docker)
  • Java 8+
  • Lombok ≥ 1.18.18
  • Maven ≥ 3.6.2

Quarkus extensions

$ ./mvnw quarkus:add-extension -Dextensions="quarkus-hibernate-reactive-panache,quarkus-reactive-pg-client,quarkus-resteasy-reactive-jsonb,quarkus-smallrye-graphql"

This guide is based on the findings in this guide.

QUARKUS — SMALLRYE GRAPHQL

Entities Design

Having a many to many entity relationship needs to be normalized for better structure. This is done by breaking out a new entity describing the relation between movie and actor into a ActorMovieRelation table which will be our bridging table.

Declaring the Actor Panache Entity

Declaring the Movie Panache Entity

Declaring the Actor Movie Relation Panache Entity

Reactive GraphQL queries

Queries can be made reactive by using Uni, or CompletionStage as a return type, for example. We will be using the reactive approach using smallrye-mutiny reactive streams.

The GraphQL Actor API

The GraphQL Movie API

Configuration

Running

Running the PostgreSQL db.

$ docker run -d --rm --name my_reative_db -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password -e POSTGRES_DB=my_db -p 5432:5432 postgres:10.5

Running the quarkus application with live coding preview.

$ ./mvnw compile quarkus:dev

GraphQL generated schema

This will be generated from our GraphQL annotated classes. Located at

http://localhost:8080/graphql/schema.graphql

Quarkus GraphQL UI

This is enabled per default and the UI is located at

http://localhost:8080/q/graphql-ui/

Add the following queries to the GraphQL editor and start interacting.

mutation addActorToMovie {
addActorToMovie(movieId: 1, actorId: 1) {
title
releaseDate
director
actors {
name
id
}
}
}
mutation addMovieToActor {
addMovieToActor(movieId: 3, actorId: 3) {
name
id
movies {
title
actors {
name
}
}
}
}
query allActors {
allActors {
name
id
movies {
title
director
id
releaseDate
actors {
name
}
}
}
}
query allMovies {
allMovies {
title
releaseDate
director
id
actors {
name
id
}
}
}
mutation deleteMovie {
deleteMovie(movieId: 2)
}
mutation updateMovie {
updateMovie(movieId: 1, movie: {title: "rEsErvOiR d0Gs"}) {
title
}
}

Conclusion

As seen, we can immediately start interacting with our different API resources and entities. More operations and examples can be found in the GitHub repo.

Find the GitHub source project here

Good luck!

--

--