- Java 21
- install e.g. using sdkman:
sdk install java 21.0.3-tem
- install e.g. using sdkman:
- Gradle 8.8
- install e.g. using sdkman:
sdk install gradle 8.8
- install e.g. using sdkman:
- containerd & nerdctl or docker
- Rancher Desktop highly recommended: https://rancherdesktop.io/
Build process is designed for building optimal structure for container image. Traditionally Java apps are built and deployed as JARs, but for optimized container image, we want to have layered directory structure instead.
Following command will build directories that can be copied as image layers:
./gradlew clean compileJava bootDir
Locally we usually want to launch the container in addition to just building image.
Following command will build the image and launch app container and DB container:
docker compose up
or:
nerdctl compose up
curl -X POST http://localhost:10000/api/sku --header "Content-Type: application/json" --data '{ "price": 10 }'
curl -X GET http://localhost:10000/api/sku/1
curl -X PUT http://localhost:10000/api/sku/1 --header "Content-Type: application/json" --data '{ "price": 20 }'
or:
curl -X PATCH http://localhost:10000/api/sku/1 --header "Content-Type: application/json" --data '{ "price": 30 }'
curl -X DELETE http://localhost:10000/api/sku/1
curl -X GET http://localhost:10000/api/sku?priceMin=10&priceMax=40
PostgreSQL container is included as a database for local testing purpose.
DB can also be accessed from host machine using following settings:
- username: apiuser
- password: apipassword
- port: 11000
- database: apidb
- api/request
- API request DTOs
- api/response
- API response DTOs
- api/...Controller.java
- API controller classes that handle requests and responses
- repository/entity
- database entity classes, including table definitions
- repository/...Repository.java
- repository interfaces that handle access to database
- common queries are autogenerated and custom queries can be defined
- service/
- service layer classes that function as a layer between controllers and repositories
- core business logic should be kept here
- resources/application.yaml
- app configuration
- currently configuration is included in the app image, but normally it would be mounted during runtime e.g. as Kubernetes ConfigMap
- resources/schema.sql
- DB schema used for bootstrapping database
- normally schema changes would be handled manually in order not to cause unexpected changes during deployment
- test/
- test code would go under here, but has been excluded due to time constraint
- build.gradle.kts
- main build configuration
- gradle/lib.versions.toml
- dependency definitions
Following have been left out due to time constraint:
- authentication and authorization logic
- dynamic configuration (e.g. via Kubernetes ConfigMap)
- test code
- logging
- basic logging is included, but more fine-grained logging should be implemented for easier debugging
- error handling
- basic error handling is included, but proper error handling should be implemented for corner cases and proper API responses