springboot-graphql-databases
springboot-graphql-databases copied to clipboard
The goal of this project is to explore GraphQL. For it, we will implement two microservices: author-book-api and book-review-api.
springboot-graphql-databases
The goal of this project is to explore GraphQL. For it, we will implement two Spring Boot Web Java applications: author-book-api and book-review-api.
Note: In
kubernetes-minikube-environmentrepository, it's shown how to deploy this project inKubernetes(Minikube).
Proof-of-Concepts & Articles
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
Additional Readings
- [Medium] Implementing and Securing a Spring Boot GraphQL API with Keycloak
- [Medium] Implementing and Securing a Spring Boot GraphQL API with Okta
Project Diagram

Applications
-
author-book-api
Spring BootWeb Java application that handlesauthorsandbooks. It exposes aGraphQLendpoint and traditional REST API endpoints.author-book-apiusesMySQLas storage and callsbook-review-apito get the reviews of the books. It usesFeignto easily create a client forbook-review-apiandResilience4j(fault tolerance library) to handle fallback whenbook-review-apiis down. The bookISBNis what connects books stored inauthor-book-apiwith the ones stored inbook-review-api. -
book-review-api
Spring BootWeb Java application that handlesbooksand theirreviews. It only exposes aGraphQLAPI and usesMongoDBas storage.
Frontend applications
In the repository react-graphql-databases, I have implemented two ReactJS applications author-book-ui and book-review-ui that are frontend applications for author-book-api and book-review-api, respectively.
If you want to see the complete communication frontend-backend using GraphQL, clone the react-graphql-databases and follow the README instructions.
Prerequisites
Start Environment
-
Open a terminal and inside
springboot-graphql-databasesroot folder run:docker compose up -d -
Wait for Docker containers to be up and running. To check it, run:
docker compose ps
Run applications with Maven
Inside springboot-graphql-databases, run the following Maven commands in different terminals:
-
author-book-api
./mvnw clean spring-boot:run --projects author-book-api \ -Dspring-boot.run.jvmArguments="-Dspring.datasource.username=authorbookuser -Dspring.datasource.password=authorbookpass" -
book-review-api
./mvnw clean spring-boot:run --projects book-review-api \ -Dspring-boot.run.jvmArguments="-Dspring.data.mongodb.username=bookreviewuser -Dspring.data.mongodb.password=bookreviewpass"
Run Applications as Docker containers
Build Application's Docker Images
In a terminal and inside springboot-graphql-databases root folder, run the following script:
./docker-build.sh
Application's environment variables
-
author-book-api
Environment Variable Description MYSQL_HOSTSpecify host of the MySQLdatabase to use (defaultlocalhost)MYSQL_PORTSpecify port of the MySQLdatabase to use (default3306)ZIPKIN_HOSTSpecify host of the Zipkindistributed tracing system to use (defaultlocalhost)ZIPKIN_PORTSpecify port of the Zipkindistributed tracing system to use (default9411)BOOK_REVIEW_API_HOSTSpecify host of the book-review-apiservice (defaultlocalhost)BOOK_REVIEW_API_PORTSpecify port of the book-review-apiservice (default9080) -
book-review-api
Environment Variable Description MONGODB_HOSTSpecify host of the MongoDBdatabase to use (defaultlocalhost)MONGODB_PORTSpecify port of the MongoDBdatabase to use (default27017)ZIPKIN_HOSTSpecify host of the Zipkindistributed tracing system to use (defaultlocalhost)ZIPKIN_PORTSpecify port of the Zipkindistributed tracing system to use (default9411)
Start Applications as Docker containers
In a terminal and inside springboot-graphql-databases root folder, run following script:
./start-apps.sh
Application's Link
| Application | URL Type | URL |
|---|---|---|
| author-book-api | Swagger | http://localhost:8080/swagger-ui.html |
| author-book-api | GraphiQL | http://localhost:8080/graphiql |
| book-review-api | GraphiQL | http://localhost:9080/graphiql |
How to use GraphiQL
-
book-review-api
-
In a browser, access http://localhost:9080/graphiql;
-
Create a book and return its id:
mutation { createBook(bookInput: {title: "Getting Started With Roo", isbn: "9781449307905"}) { id } } -
Add one review for the book created above, suppose the id is
5bd4bd4790e9f641b7388f23:mutation { addBookReview(bookId: "5bd4bd4790e9f641b7388f23", reviewInput: {reviewer: "Ivan Franchin", comment: "It is a very good book", rating: 5}) { id } } -
Get all books stored in
book-review-api, including their reviews:{ getBooks { id title isbn reviews { comment rating reviewer createdAt } } }
-
-
author-book-api
-
In a browser, access http://localhost:8080/graphiql;
-
Create an author and return the author id:
mutation { createAuthor(authorInput: {name: "Josh Long"}) { id } } -
Create a book and return the book id and author name:
Note: while creating this book in
author-book-api, we are setting the same ISBN,9781449307905, as we did when creating the book inbook-review-api.mutation { createBook(bookInput: {authorId: 1, isbn: "9781449307905", title: "Getting Started With Roo", year: 2020}) { id author { name } } } -
Get author by id and return some information about his/her books including book reviews from
book-review-api:Note: as the book stored in
author-book-apiandbook-review-apihas the same ISBN,9781449307905, it's possible to retrieve the reviews of the book. Otherwise, an empty list will be returned in casebook-review-apidoes not have a specific ISBN or the service is down.{ getAuthorById(authorId: 1) { name books { isbn title bookReview { reviews { reviewer rating comment createdAt } } } } } -
Update book title and return its id and new title:
mutation { updateBook(bookId: 1, bookInput: {title: "Getting Started With Roo 2"}) { id title } } -
Delete the author and return author id:
mutation { deleteAuthor(authorId: 1) { id } }
-
Useful links & commands
-
Zipkin
It can be accessed at http://localhost:9411.
-
MySQL monitor
docker exec -it -e MYSQL_PWD=authorbookpass mysql mysql -uauthorbookuser --database authorbookdb SHOW tables; SELECT * FROM authors; SELECT * FROM books;Type
exitto get out of MySQL monitor -
MongoDB shell
docker exec -it mongodb mongosh -u bookreviewuser -p bookreviewpass --authenticationDatabase bookreviewdb use bookreviewdb; db.books.find().pretty();Type
exitto get out of MongoDB shell
Shutdown
- To stop applications:
- If they were started with
Maven, go to the terminals where they are running and pressCtrl+C; - If they were started as a Docker container, go to a terminal and, inside
springboot-graphql-databasesroot folder, run the script below:./stop-apps.sh
- If they were started with
- To stop and remove docker compose containers, network and volumes, go to a terminal and, inside
springboot-graphql-databasesroot folder, run the following command:docker compose down -v
Cleanup
To remove the Docker images created by this project, go to a terminal and, inside springboot-graphql-databases root folder, run the following script:
./remove-docker-images.sh
TODO
- implement test cases;
- use
HttpGraphQlClientto callbook-reviewinstead offeign(we need to convert to project toWebFlux); - study how to implement authentication/authorization to
GraphQLendpoint; - implement
graphqlsubscription;
References
- https://graphql.org/learn
- https://www.pluralsight.com/guides/building-a-graphql-server-with-spring-boot
- https://www.baeldung.com/spring-graphql
- https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/