Author: Kenneth Kousen
License: MIT License
Spring Boot Version: 3.5.5
Java Version: 21+
This project implements a complete service layer architecture for an Item Management System using Spring Boot. It demonstrates proper separation of concerns with controller, service, and repository layers, following SOLID principles and best practices.
The application follows a three-layer architecture:
┌─────────────────────────┐
│ Controller Layer │ (REST endpoints)
├─────────────────────────┤
│ Service Layer │ (Business logic & validation)
├─────────────────────────┤
│ Repository Layer │ (In-memory data storage)
└─────────────────────────┘
- Generic Repository Interface (
Repository<T, ID>): Defines standard CRUD operations - ItemRepository Interface: Extends the generic repository with domain-specific queries
- InMemoryItemRepository: Thread-safe implementation using
ConcurrentHashMap
- BaseService Abstract Class: Provides common CRUD operations and validation framework
- ItemService: Concrete implementation with business logic and collection operations
- ItemController: RESTful endpoints for item management
- Item Entity: Domain model with id, name, and category fields
- ✅ Full CRUD operations for items
- ✅ Category-based filtering
- ✅ Name-based search with case-insensitive matching
- ✅ Collection operations (grouping, unique categories)
- ✅ Thread-safe in-memory storage
- ✅ Input validation
- Map: Group items by category
- Set: Extract unique categories
- List: Maintain ordered item collections
- Stream API: Filter, map, and collect operations
- Defensive Copying: Protect internal state
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/items |
Get all items |
| GET | /api/items/{id} |
Get item by ID |
| GET | /api/items/category/{category} |
Get items by category |
| GET | /api/items/search?name={name} |
Search items by name |
| GET | /api/items/categories |
Get all unique categories |
| GET | /api/items/grouped |
Get items grouped by category |
| POST | /api/items |
Create new item |
| PUT | /api/items/{id} |
Update existing item |
| DELETE | /api/items/{id} |
Delete item |
The project includes comprehensive test coverage:
- ItemRepositoryTest: Repository layer unit tests
- ItemServiceTest: Service layer unit tests with mocked repository
- ItemIntegrationTest: Full integration tests with MockMvc
# Run all tests
./gradlew test
# Generate coverage report
./gradlew jacocoTestReport
# View coverage report
open build/reports/jacoco/test/html/index.html- Target: 80% code coverage across all layers
- JaCoCo plugin configured for automatic coverage reporting
- Coverage verification integrated with build process
This project is designed to be completed by teams. Follow these steps to set up your team's development environment:
One team member should be designated as the repository owner:
- Navigate to the original repository: https://github.com/kousen/assignment-2-service-layer
- Click the "Fork" button in the top-right corner
- Select your personal GitHub account
- This creates your team's working repository
Each team member should clone the team's forked repository:
# Replace [team-lead-username] with the GitHub username of whoever forked the repo
git clone https://github.com/[team-lead-username]/assignment-2-service-layer.git
cd assignment-2-service-layerAll team members should set up the original repository as the upstream remote to receive updates:
# Add the original repository as upstream
git remote add upstream https://github.com/kousen/assignment-2-service-layer.git
# Verify your remotes
git remote -v
# You should see:
# origin https://github.com/[team-lead-username]/assignment-2-service-layer.git (fetch)
# origin https://github.com/[team-lead-username]/assignment-2-service-layer.git (push)
# upstream https://github.com/kousen/assignment-2-service-layer.git (fetch)
# upstream https://github.com/kousen/assignment-2-service-layer.git (push)To get updates from the original repository:
# Fetch updates from upstream
git fetch upstream
# Merge upstream changes into your main branch
git checkout main
git merge upstream/main
# Push updates to your team's fork
git push origin main-
Create feature branches for different parts of the assignment:
git checkout -b feature/repository-layer git checkout -b feature/service-layer git checkout -b feature/controller-layer
-
Push branches to your team's fork:
git push origin feature/your-branch-name
-
Create Pull Requests within your team's fork for code review
-
Ensure all team members have commits in the final submission
- Java 21 or higher
- Gradle 8.x or higher
- Git
- GitHub account
After completing the Team Collaboration Setup:
- Build the project:
./gradlew build- Run the application:
./gradlew bootRunThe application will start on http://localhost:8080
Create an item:
curl -X POST http://localhost:8080/api/items \
-H "Content-Type: application/json" \
-d '{"name":"Sample Item","category":"Electronics"}'Get all items:
curl http://localhost:8080/api/itemsSearch by category:
curl http://localhost:8080/api/items/category/Electronicsassignment-2-service-layer/
├── src/
│ ├── main/
│ │ └── java/
│ │ └── edu/trincoll/
│ │ ├── Assignment2Application.java
│ │ ├── model/
│ │ │ └── Item.java
│ │ ├── repository/
│ │ │ ├── Repository.java
│ │ │ ├── ItemRepository.java
│ │ │ └── InMemoryItemRepository.java
│ │ ├── service/
│ │ │ ├── BaseService.java
│ │ │ └── ItemService.java
│ │ └── controller/
│ │ └── ItemController.java
│ └── test/
│ └── java/
│ └── edu/trincoll/
│ ├── repository/
│ │ └── ItemRepositoryTest.java
│ ├── service/
│ │ └── ItemServiceTest.java
│ └── integration/
│ └── ItemIntegrationTest.java
- Repository Pattern: Abstracts data access logic
- Template Method Pattern: BaseService provides template for CRUD operations
- Dependency Injection: Constructor-based DI throughout
- Factory Pattern: ID generation in repository
- Single Responsibility: Each layer has a distinct responsibility
- Open/Closed: BaseService is open for extension, closed for modification
- Liskov Substitution: ItemService can be substituted for BaseService
- Interface Segregation: Repository interfaces are focused and cohesive
- Dependency Inversion: Controllers depend on abstractions (services), not concrete implementations
This project was developed with assistance from Claude AI for:
- Initial project structure setup
- Test case generation
- Documentation formatting
All code has been reviewed, tested, and validated to ensure correctness and adherence to best practices.
This project is licensed under the MIT License - see the LICENSE file for details.
Kenneth Kousen
- Trinity College Computer Science Department
- Spring Boot Documentation
- JUnit Testing Framework