This is a solution for Mytheresa backend challenge.
Provided implementation contains two different interfaces: DiscountService
and ProductsService
.
This approach allows one to easily replace implementation of specific service. There are two implementations of the services:
DBBackedProductsServiceImpl
is JPA-backend implementation ofProductsService
that relies on usage of RDBMS for storing products;DiscountServiceImpl
is very simple implementation ofDiscountService
that provides a way of compile-time configuring of SKU's and categories to apply specific discounts for.
At the storage level two SQL tables are used: one for products, one for categories. This approach enables one to rename categories easily. Categories are not exposed as interface (like products) because there is no need for this. For «real world» application it may be reasonable to expose categories and implement many-to-many relationship between categories and products.
Implementation uses Controller-Service-Repository architecture. Each layer puts minimal possible restrictions on API.
For example ProductsRepository
has no limitation for response size. Instead it provides a parameter that enables caller
to specify paging parameters. ProdutsService
puts another restriction: it's possible to request for «one page» only,
but page size may be specified explicitly if necessary. ProductsController
is the one in charge of enforcing result set
size to never exceed 5 as required by task description.
There are two types of tests provided:
- Unit tests (
DiscountServiceImplTest
) are supposed to validate services implementation. These tests do not use Spring
for dependency injection but are written in implementation-agnostic way. - Integration tests (
ProductsIT
) are supposed to ensure REST API satisfies all requirements (e.g. response format, max response size etc.). Few of them in some sense duplicate unit tests.
Please note that the following scenario is tested only on Linux environment. It heavily relies on Maven and Docker so it should work for other platforms (MacOS, Windows with WSL), but some minor tweaks may be required.
To run both unit and integration tests use
mvn clean verify
To build project use
mvn -P docker -D maven.test.skip=true package
To run demo project use supplied script run_demo.sh
that does the following:
- builds Docker image for backend;
- generates input data with size of 100k products;
- runs backend and PostgreSQL containers using
docker-compose
.
Backend API will be accessible at http://127.0.0.1:8080/products/
with Swagger UI at http://127.0.0.1:8080/swagger/swagger-ui.html
.