A comprehensive Spring Boot REST API demonstration project designed to help novice developers learn API development and OpenAPI documentation generation.
This project serves as a practical learning resource for:
- REST API Design - Modern API patterns and best practices
- Spring Boot Development - Controller, service, and model layer architecture
- OpenAPI 3.0 Specification - Professional API documentation generation
- API Testing - Unit tests, integration tests, and interactive testing
- HTTP Methods & Status Codes - Proper usage of GET, POST, PUT, PATCH, DELETE
- Data Modeling - Entity relationships and nested objects
- Error Handling - Custom exceptions and validation patterns
- Java 17 or higher
- Maven 3.6 or higher
# Build and start the application
./mvnw spring-boot:run
# The application will start on http://localhost:8080- Swagger UI: http://localhost:8080/swagger-ui/index.html
- OpenAPI JSON: http://localhost:8080/v3/api-docs
Learning Focus: Request body handling, validation, nested objects
POST /customer
{
"id": "CUST001",
"name": "Alice Johnson",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zipCode": "10001",
"country": "USA"
},
"phone": "555-0123",
"type": "VIP"
}Key Concepts:
- JSON request body binding with
@RequestBody - Nested object serialization (Address within Customer)
- Enum validation (CustomerType: INDIVIDUAL, BUSINESS, VIP, PREMIUM)
- Custom validation and error responses
Learning Focus: Path variables, error handling
GET /customer/CUST001Key Concepts:
- Path variable binding with
@PathVariable - Custom exception handling (
CustomerNotFoundException) - HTTP status codes (200 OK, 404 Not Found)
Learning Focus: Full resource replacement
PUT /customer
{
"id": "CUST001",
"name": "Alice Johnson Updated",
"address": { /* complete address object */ },
"phone": "555-9999",
"type": "PREMIUM"
}Key Concepts:
- PUT semantics (complete resource replacement)
- Idempotent operations
- Business logic validation
Learning Focus: Partial updates, dynamic field handling
PATCH /customer/CUST001
{
"name": "Updated Name Only",
"phone": "555-8888"
}Key Concepts:
- PATCH semantics (partial updates)
- Dynamic field processing with
Map<String, Object> - Nested object partial updates
- Field-level validation
Learning Focus: Resource deletion patterns
DELETE /customer/CUST001Key Concepts:
- DELETE method semantics
- Idempotent deletion
- Error handling for non-existent resources
Learning Focus: Query parameters, pagination patterns
GET /customers?page=0&size=10&name=Alice&type=VIP&city=New York&state=NYKey Concepts:
- Query parameter binding with
@RequestParam - Default parameter values
- Optional parameters (
required = false) - Pagination response wrapper (
PaginatedResponse<T>) - Filter combinations and business logic
Learning Focus: Complex search criteria, request body alternatives
POST /customers/search
{
"name": "Alice",
"type": "VIP",
"city": "New York",
"state": "NY",
"zipCode": "10001",
"phoneAreaCode": "555",
"minAge": 25,
"maxAge": 65
}Key Concepts:
- When to use POST for search (complex criteria)
- Search criteria objects
- Range validation (age ranges)
- Multiple filter combinations
Learning Focus: Array processing, batch validation
POST /customers/batch
[
{
"id": "BATCH001",
"name": "Batch Customer 1",
/* ... */
},
{
"id": "BATCH002",
"name": "Batch Customer 2",
/* ... */
}
]Key Concepts:
- Array/List handling in REST APIs
- Individual item validation within batches
- Partial success scenarios
- Batch size limitations
src/main/java/com/restexample/restdemo/
├── RestDemoApplication.java # Spring Boot application entry point
├── config/
│ └── OpenApiConfig.java # OpenAPI configuration and metadata
├── controller/
│ └── CustomerAPIService.java # REST endpoints and request handling
├── model/
│ ├── Customer.java # Main entity with business methods
│ ├── CustomerType.java # Enum for customer types
│ ├── CustomerList.java # In-memory data management
│ ├── Address.java # Nested entity example
│ ├── CustomerSummary.java # Lightweight response model
│ ├── CustomerSearchCriteria.java # Search request model
│ └── PaginatedResponse.java # Generic pagination wrapper
└── exception/
├── CustomerNotFoundException.java # Custom domain exception
├── ValidationException.java # Input validation exception
├── CustomerException.java # Exception response wrapper
└── CustomerExceptionHandler.java # Global exception handling
- Single responsibility (HTTP handling only)
- Clear endpoint organization
- Comprehensive input validation
- Proper HTTP status code usage
- Entity design with business methods
- Enum usage for type safety
- Nested object relationships
- Response models vs domain models
- Custom domain exceptions
- Global exception handler with
@ControllerAdvice - Consistent error response format
- Proper HTTP status mapping
- Request/Response models
- Pagination wrapper pattern
- Search criteria pattern
- Batch operation pattern
Located in config/OpenApiConfig.java:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Customer Management API")
.version("1.0.0")
.description("Comprehensive REST API demonstration...")
.contact(/* contact info */)
.license(/* license info */))
.servers(List.of(
new Server().url("http://localhost:8080").description("Development server"),
new Server().url("https://api.example.com").description("Production server")
));
}Learning Points:
- API versioning strategies
- Environment-specific server configurations
- Professional metadata for API consumers
- Contact and licensing information
@Tag(name = "Customer Management", description = "REST API for managing customer data...")
public class CustomerAPIService {@Operation(
summary = "Create a new customer",
description = """
Creates a new customer with complete profile information...
This endpoint demonstrates:
- Nested object handling (Address within Customer)
- Enum validation (CustomerType)
- Input validation and error handling
""",
tags = {"CRUD Operations"}
)@Parameter(
description = "Unique identifier of the customer",
example = "CUST001"
)
@PathVariable String customerID@ApiResponses({
@ApiResponse(responseCode = "200", description = "Customer created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid customer data provided")
})The OpenAPI specification automatically generates:
- Interactive API Testing - Try endpoints directly from Swagger UI
- Request/Response Examples - Auto-generated from your models
- Schema Documentation - Complete data model documentation
- Validation Rules - Derived from your validation annotations
- Error Response Documentation - Based on your exception handling
- CustomerAPIServiceTest.java - Controller method testing with MockMvc
- CustomerTypeTest.java - Enum functionality testing
- RestDemoApplicationTests.java - Spring context loading
./mvnw test- Complete API workflow testing
- Error scenario validation
- End-to-end request/response verification
./test-api-integration.sh- Real-time API exploration
- Parameter experimentation
- Response inspection
- Authentication testing (if implemented)
- Add New Fields: Add an
emailfield to the Customer model - Extend Validation: Add email format validation
- New Endpoint: Create a
GET /customers/countendpoint - Custom Response: Create a CustomerDetails response model
- Add Authentication: Implement basic API key authentication
- Add Logging: Add request/response logging
- Database Integration: Replace in-memory storage with JPA
- Add Caching: Implement response caching
- API Versioning: Implement v1 and v2 API versions
- Rate Limiting: Add request throttling
- Async Processing: Implement async batch operations
- Metrics Integration: Add API metrics and monitoring
# Clean build
./mvnw clean compile
# Run application
./mvnw spring-boot:run
# Build JAR file
./mvnw clean package
# Run built JAR
java -jar target/rest-demo-0.0.1-SNAPSHOT.jar# Run all tests
./mvnw test
# Run specific test class
./mvnw test -Dtest=CustomerAPIServiceTest
# Run tests with coverage
./mvnw test jacoco:report# Auto-reload on changes
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=dev"
# Skip tests during development builds
./mvnw clean package -DskipTests| Method | Endpoint | Purpose | Key Learning Concepts |
|---|---|---|---|
| POST | /customer |
Create customer | Request body, validation, nested objects |
| GET | /customer/{id} |
Get by ID | Path variables, error handling |
| PUT | /customer |
Update customer | Full resource replacement |
| PATCH | /customer/{id} |
Partial update | Dynamic field updates |
| DELETE | /customer/{id} |
Delete customer | Resource deletion |
| GET | /customers |
List with pagination | Query parameters, pagination |
| POST | /customers/search |
Advanced search | Complex criteria, POST for search |
| POST | /customers/batch |
Batch create | Array processing, partial success |
- Explore the Swagger UI - Start with http://localhost:8080/swagger-ui/index.html
- Run the Tests - Execute
./mvnw testto see comprehensive testing patterns - Modify and Experiment - Try the learning exercises above
- Study the Code - Compare controller annotations with generated documentation
- Build Your Own API - Apply these patterns to your own domain model