Demonstrations of my proficiency span across several technologies. Concretely, this project is an API facilitating CRUD operations (Create, Read, Update, Delete (TODO)) for various objects. You can explore the object relationship schema here, which is heavily inspired by Sakila Sample Database.
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Table of Contents
Being a passionate web developer, I am always in search of captivating challenges. Driven by the desire to find/craft solutions to some issues that I've encountered in my prior roles, I conceived this project as a platform to exhibit the solutions I've implemented. This also serves as a testament to my proficiency in crafting elegant and effective problem-solving approaches.
- Netflix DGS Framework
- JPA
- Spring Filter
- Lombok
- MapStruct
- JPA 2 Metamodel Generator
- Netflix DGS Code Generation Plugin
I've opted to utilize the Netflix DGS Framework (GraphQL) for the development of my Spring project. This choice stems from my previous experiences with RESTful APIs during my prior roles. I found that conventional RESTful approaches often led to overfetching of data, without a clear understanding of whether the recipient truly required all the retrieved information. Additionally, optimizing these calls (by creating specialize DAO view for specific use cases) proved to be error-prone and time-consuming due to the need for duplicated code.
To address these concerns, the GraphQL approach offers a more efficient solution. By adopting the Netflix DGS Framework, I can focus on creating a GraphQL application that enables clients to request precisely the data they need, reducing unnecessary data retrieval.
To tackle the N+1 query issue inherent in JPA and Hibernate, the DGS Framework introduces the concept of Data Loaders. Data Loaders allow enhancing efficiency by batching and caching database queries. Detailed information on this approach can be found here. Please be aware that my current implementation is solely a proof of concept, requiring further refinement before it can be deemed production-ready.
To overcome the performance issue associated with SQL offset pagination, I've implemented a KeySet pagination. This ensures that I can paginate through SQL tables of any size without encountering the performance drawbacks associated with traditional SQL offset approaches. See the KeysetPaginationService class for more details.
To enable straightforward filtering capabilities, I've integrated the underrated Spring Filter library. This library allows converting complex string-based filters into JPA Specifications, greatly simplifying the process of applying filters to various fields. While my implementation might not yet be production-ready, it provides a simple yet effective mechanism for filtering. See the KeysetPaginationService class for more details.
To facilitate seamless and efficient mapping between Data Transfer Objects (DTOs) and Data Access Objects (DAOs), I've harnessed the power of MapStruct. MapStruct is a Java annotation processor for the generation of type-safe and performant mappers for Java bean classes. It saves you from writing mapping code by hand, which is a tedious and error-prone task.
To get a local copy up and running, follow these simple steps.
Before diving into the installation section, make sure your system meets the following prerequisites:
1.1. Clone the Repository:
Start by cloning the Docker Compose repository using the following command:
git clone https://github.com/sisimomo/graphqlSakila.git
1.2. Navigate to the Local Folder:
Move into the local folder within the cloned repository:
cd ./graphqlSakila/docker-compose/local
1.3. Configure Environment Variables:
Duplicate the .env.sample
file and rename it to .env
:
cp ./.env.sample ./.env
Customize the variables in the .env
file to your preferences.
1.4. Initiate Docker Compose:
Start docker containers using Docker Compose:
docker-compose up -d
2.1. Open in IntelliJ:
Open the cloned repository folder using IntelliJ IDEA.
2.2. Update Environment Variables:
Adjust the environment variables according to your .env
modifications in the "Run/Debug configuration" named "Local" located in the .run
folder within the cloned repository.
2.4. Start the Application:
Launch the application using the "Run/Debug configuration" named "Local" in IntelliJ.
Feel free to explore the code and provide suggestions for enhancement by creating feature requests through new GitHub issues.
Distributed under the MIT License. See LICENSE
for more information.