True-To-Size Sneaker software sample for StockX. Full requirements outlined in project-spec.pdf
.
This application requires Docker to be installed on the target machine. Either a local installation of gradle
or the
provided gradlew
executable can be used to interface with this project's build cycle.
Clone this repository and download dependencies from Maven Central, ideally by loading the project in a Java IDE. Once fully downloaded, the application can be executed by running the command:
$ gradle bootrun
This will pull a postgres image which will automatically load via docker-compose
. Database connection options can be
configured in the configuration profile src/main/resources/application.yml
1.
This project is a web server written in Java 11 which exposes two endpoints:
This endpoint expects the following JSON Request Body:
{
"id": string,
"trueToSizeValue": 1 | 2 | 3 | 4 | 5
}
When this endpoint is called with valid data, that data will be persisted to the database's sneaker-crowdsource-data
table; if no data has ever been recorded for the provided id
(the sneaker identifier), a record will be created in the
Sneakers
table for this entity. At this time, id
is expected to be the name of the shoe, provided in the following
template2:
<manufacturer> <product name>
e.g. adidas Yeezy
This endpoint will return the following statuses in the provided scenarios:
200
: Operation is successful400
: User has provided a malformed request500
: Error communicating with database
This endpoint is called with no request body; the product ID is provided via route parameter. Calling this endpoint will return:
200 [Double]
: The true-to-size value calculated as the average of all crowdsourced data for the givenproductId
204
: The operation was successful, but no data exists for the providedproductId
500
: Error communicating with database
This application is built with Spring Framework, which eases the development process by providing essentials like dependency injection and HTTP exposure, and helps generate readable, maintainable code with easy-to-read annotation-driven abstractions as well as a gamut of customizable testing utilities.
This project is using Gradle to execute builds, run automated tests, and manage dependencies.
This project uses JUnit 4 with AssertJ and Mockito. All automated tests can be run by executing the following command:
$ gradle test
This project uses Prometheus for reporting metrics. Provided metrics are
exposed via Spring Boot Actuator and Prometheus. This appears as a separate server that is running on port 8079
(configurable via src/main/resources/application.yml
) and is accessible by executing the following request:
[GET] localhost:8079/actuator/prometheus
This application uses Postgres, a SQL database system. Internally, the source code leverages Spring Data JPA for all
database interactions. Currently, database creation configuration is stored in docker-compose.yml
1;
database connection configuration is stored in src/main/resources/application.yml
.
This project is configured to use Jib as part of its build process. First, a container registry must be defined in
build.gradle
by configuring jib.to.image
; all subsequent gradle build
s will automatically containerize this
application and push to the registry.
Additionally, this project uses a Postgres instance. In order to make this codebase portable to other developer
machines, docker-compose
is used to automatically pull and load the Postgres image. To run just the Postgres image,
for example to work with certain IDEs or workflows, run:
$ docker-compose up
1 In an actual project, the application.yml
containing database connection credentials, as well as the
credentials stored in docker-compose.yml
would not be committed to version control. Additionally, a more secure
password than postgres
would be used.
2 Persisting database information with a key as loosely defined as a product name is risky, and properly done requires data normalization, error approximation, similar-key-lookups, etc. For this type of system, a more digital product identifier would be ideal, such as an external UPC or an internal SKU; a product lookup could be provided to users via a front-end application. For this project, I've opted out of a complex normalization strategy due to lack of specification, though the code is written with this type of refactoring in mind.
3 I would never proclaim to be an infrastructure expert; I've designed this system to the best of my ability, though porting to additional developer machines or executing remotely may require some tweaking and configuring here and there. I also would like to thank whoever is reading this last line of the README for their time and consideration. I've had the opportunity to dabble in areas of the process I'm less familiar with and have learned a lot from this project.