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-environment
repository, it's shown how to deploy this project inKubernetes
(Minikube
).
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.
- [Medium] Implementing and Securing a Spring Boot GraphQL API with Keycloak
- [Medium] Implementing and Securing a Spring Boot GraphQL API with Okta
-
Spring Boot
Web Java application that handlesauthors
andbooks
. It exposes aGraphQL
endpoint and traditional REST API endpoints.author-book-api
usesMySQL
as storage and callsbook-review-api
to get the reviews of the books. It usesFeign
to easily create a client forbook-review-api
andResilience4j
(fault tolerance library) to handle fallback whenbook-review-api
is down. The bookISBN
is what connects books stored inauthor-book-api
with the ones stored inbook-review-api
. -
Spring Boot
Web Java application that handlesbooks
and theirreviews
. It only exposes aGraphQL
API and usesMongoDB
as storage.
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.
-
Open a terminal and inside
springboot-graphql-databases
root folder run:docker compose up -d
-
Wait for Docker containers to be up and running. To check it, run:
docker compose ps
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"
In a terminal and inside springboot-graphql-databases
root folder, run the following script:
./docker-build.sh
-
author-book-api
Environment Variable Description MYSQL_HOST
Specify host of the MySQL
database to use (defaultlocalhost
)MYSQL_PORT
Specify port of the MySQL
database to use (default3306
)ZIPKIN_HOST
Specify host of the Zipkin
distributed tracing system to use (defaultlocalhost
)ZIPKIN_PORT
Specify port of the Zipkin
distributed tracing system to use (default9411
)BOOK_REVIEW_API_HOST
Specify host of the book-review-api
service (defaultlocalhost
)BOOK_REVIEW_API_PORT
Specify port of the book-review-api
service (default9080
) -
book-review-api
Environment Variable Description MONGODB_HOST
Specify host of the MongoDB
database to use (defaultlocalhost
)MONGODB_PORT
Specify port of the MongoDB
database to use (default27017
)ZIPKIN_HOST
Specify host of the Zipkin
distributed tracing system to use (defaultlocalhost
)ZIPKIN_PORT
Specify port of the Zipkin
distributed tracing system to use (default9411
)
In a terminal and inside springboot-graphql-databases
root folder, run following script:
./start-apps.sh
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 |
-
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-api
andbook-review-api
has the same ISBN,9781449307905
, it's possible to retrieve the reviews of the book. Otherwise, an empty list will be returned in casebook-review-api
does 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 } }
-
-
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
exit
to 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
exit
to get out of MongoDB shell
- 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-databases
root 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-databases
root folder, run the following command:docker compose down -v
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
- implement test cases;
- use
HttpGraphQlClient
to callbook-review
instead offeign
(we need to convert to project toWebFlux
); - study how to implement authentication/authorization to
GraphQL
endpoint; - implement
graphql
subscription;