Assignee: @team Sprint: Backlog (onboarding) Estimated effort: 4–6h Generated: 2026-03-02 Last updated: 2026-03-02
Title: [TASK][INFRA] CRUD 101 — Spring Boot + MongoDB + REST API warm-up
Labels: task onboarding backend java spring
Type: ⚙️ Configuration / Setup
Sprint: Backlog (no sprint)
Estimate: 4–6h
Build a minimal but complete CRUD REST API using Java 17 + Spring Boot 3.2.2 + MongoDB. This task has no business logic — it exists purely as a warm-up exercise so the team can validate the local dev setup, get comfortable with the Spring Boot project structure, and practice writing basic unit/integration tests before working on real features.
Stack: Java 17 · Spring Boot 3.2.2 · Spring Data MongoDB · JUnit 5 · Mockito · Flapdoodle Embedded MongoDB (tests)
You will build a simple Book resource with full CRUD backed by MongoDB (already configured in this repo) and a few automated tests. At the end you should be able to:
- Run the app locally and hit all endpoints via Postman or curl
- See documents persisted in MongoDB (
ecolink_db) - Have at least one passing unit test and one passing integration test
- Project already exists at
ecolink-api-java— skip generation from start.spring.io - Imported into VS Code
-
pom.xmlalready contains:spring-boot-starter-web,spring-boot-starter-data-mongodb,spring-boot-starter-validation,lombok,spring-boot-starter-test -
application.propertiesalready configured for MongoDB:spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 spring.data.mongodb.database=ecolink_db
- Add the Flapdoodle Embedded MongoDB dependency to
pom.xmlfor integration tests:<dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo.spring3x</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency>
- Make sure MongoDB is running locally:
mongod --dbpath /your/data/path - Confirm the app starts without errors:
./mvnw spring-boot:run
- Create
Book.javain themodel/package (package exists but is empty — only a.gitkeepfile):id(String, auto-generated by MongoDB)title(String, not null, max 200 chars)author(String, not null)publishedYear(Integer)isbn(String, unique)
- Annotate with
@Document(collection = "books"),@Id,@Field,@NotBlank - Use Lombok:
@Data,@NoArgsConstructor,@AllArgsConstructor,@Builder
- Create
BookRepository.javain therepository/package (package exists but is empty — only a.gitkeepfile) - Extend
MongoRepository<Book, String> - Add one custom query method:
List<Book> findByAuthorIgnoreCase(String author)
- Create
BookService.javain theservice/package (package exists but is empty — only a.gitkeepfile) - Implement methods:
findAll(),findById(String id),findByAuthor(String author),create(Book book),update(String id, Book book),delete(String id) - Throw
ResponseStatusException(HttpStatus.NOT_FOUND)when a book is not found by ID
-
Create
BookController.javain thecontroller/package (package exists but is empty — only a.gitkeepfile) with@RestControllerand@RequestMapping("/api/books") -
Implement endpoints:
Method Path Description Success status GET /api/booksList all books 200 GET /api/books/{id}Get book by ID 200 GET /api/books?author={name}Filter by author 200 POST /api/booksCreate book 201 PUT /api/books/{id}Full update 200 DELETE /api/books/{id}Delete book 204 -
Use
@Validon@RequestBodyto trigger Bean Validation -
Return a meaningful 404 response when a book is not found
- Create
BookServiceTest.javainsrc/test/(test directory exists but has no test files) - Use
@ExtendWith(MockitoExtension.class)and@Mock BookRepository - Write at least 3 test cases:
findById_existingId_returnsBook()findById_notFound_throwsException()delete_existingId_callsRepository()
- Create
BookControllerTest.javausing@SpringBootTest+@AutoConfigureMockMvc(no test files exist yet) - Tests will run against Flapdoodle Embedded MongoDB (added in step 1 — no extra config file needed)
- Create
src/test/resources/application-test.propertiesto isolate the test database:spring.data.mongodb.database=ecolink_test_db - Annotate the test class with
@ActiveProfiles("test") - Write at least 3 integration test cases using
MockMvc:POST /api/bookswith valid payload → 201 + body containsidGET /api/books/{id}for existing book → 200 + correct fieldsGET /api/books/{id}for non-existing ID → 404
- With the app running against the local MongoDB instance, use Postman or curl to:
- Create 3 books via
POST /api/books - Retrieve the list via
GET /api/books - Update one book via
PUT /api/books/{id} - Delete one book via
DELETE /api/books/{id}
- Create 3 books via
- Open MongoDB Compass or
mongoshand confirm thebookscollection inecolink_dbreflects the operations
POST /api/books
{
"title": "Clean Code",
"author": "Robert C. Martin",
"publishedYear": 2008,
"isbn": "978-0132350884"
}Expected 201 response
{
"id": "6630f1a2b3c4d5e6f7a8b9c0",
"title": "Clean Code",
"author": "Robert C. Martin",
"publishedYear": 2008,
"isbn": "978-0132350884"
}GET /api/books/000000000000000000000099 (not found)
{
"status": 404,
"error": "Not Found",
"message": "Book with id 000000000000000000000099 not found"
}- Flapdoodle Embedded MongoDB dependency added to
pom.xml - App starts cleanly against local MongoDB with no errors
- All 6 REST endpoints respond correctly (manually verified via Postman/curl)
- Documents visible in MongoDB (
ecolink_db.books) after POST/PUT/DELETE operations - All unit tests pass:
./mvnw test - All integration tests pass using Embedded MongoDB
- No compiler warnings related to unchecked types or deprecated APIs
- Code pushed to a feature branch and PR opened for review