Used ToDo MVC features to add minor enhancements to Item (done attribute) and CRUD (filter by done). Having familiarity with DropWizard, thought this was a good chance to dabble in Spring Boot:
- Chose Jersey instead of SpringWebMvc because I prefer:
over
@GET @Path("/id")@RequestMapping(value="/id", method = RequestMethod.GET) - Used JPA to avoid SQL grunt-work. Spring Data makes this trivial with
Repositoryproviding auto-generated CRUD and queries. The REST endpoints are such a thin CRUD-wrapper that@Transactionalis overkill (but was trivial to add). - Contemplated separate
Itemclasses injpa.modelandapi.modelpackages to decouple the database and API representations (auto-converted with modelmapper) but this was premature. - Decided against Spring Data REST because HAL is really dense and verbose... also because this whole exercise would've been one file.
Thought about adding a User entity with a one-to-many relationship to Item then change the API to use HTTP Basic-Auth so that users have private To Do lists.
This all assumes you're on *nix or Mac and have Java installed. The ./gradlw.bat wrapper should work for WIndows, but I don't know about any of the docker stuff.
This uses a default application.properties that runs the service with an H2 in-memory database. Useful for local development since the database resets with service restart.
To build and run in one-step:
./gradlew bootRun
For a more production-like configuration, build the com.gmail.lnqhien/todo image:
./gradlew buildDocker
The application-gradle.properties baked into the image will make it connect to MySQL instead of H2.
Then bring up the isolated MySQL instance:
docker-compose up -d db
Once the db instance is ready (e.g.: docker logs todo_db_1), bring up the todo service:
docker-compose up -d todo
Avoid the one-shot docker-compose up since Compose's depends_on doesn't guarantee the db is ready before the todo tries to connect.
Both methods above make the service available at http://localhost:8080/todo. There is a CORS filter in place to allow browser clients to call the API.
Unit-testing with Spring-Jersey isn't as polished as SpringWebMvc and I ran out of time... so there is a rudimentary test.sh script to exercise all the available APIs:
| Endpoint | Description |
|---|---|
POST /todo |
Add a new To-Do item |
GET /todo/{id} |
Get a single To-Do item |
DELETE /todo/{id} |
Delete a single To-Do item |
PUT /todo/{id} |
Update a single To-Do item |
GET /todo |
Get all To-Do items. Supports page, size, done query parameters for pagination and filtering, e.g. GET /todo?page=1&size=5&done=false |