A comprehensive Spring Boot application with multiple modules featuring REST APIs, Microsoft Graph API integration, Webhook support, document processing, and environment-based API documentation control.
- Features
- Architecture
- Prerequisites
- Project Structure
- IntelliJ IDEA Setup
- Configuration
- Running the Application
- API Documentation
- Testing the APIs
- Module Details
- β Multi-Module Architecture: 3 service modules (User, Order, Payment) + Common module
- β Centralized API Documentation: Swagger/OpenAPI with token-based security
- β
Environment-Based Documentation Control:
- UAT: Documentation ENABLED and secured
- PROD: Documentation DISABLED for security
- β Custom Business Response Wrapper: Consistent API response format
- β Token-Based Authentication: JWT authentication for all endpoints
- β Global Exception Handling: Centralized error handling
- REST APIs: Standard CRUD operations for users
- Document Management:
- Upload documents (bills, invoices, receipts)
- Generate PDF invoices
- Email generated documents to clients
- Microsoft Graph API Integration:
- User profile management
- Send emails
- Access calendar and OneDrive
- Webhook Support:
- Register webhooks
- Receive and process webhook events
- Validate webhook signatures
- Event history tracking
multi-module-api/
βββ common/ # Shared utilities and configurations
β βββ response/ # ApiResponse wrapper
β βββ exception/ # Global exception handlers
β βββ security/ # JWT utilities
β βββ config/ # Swagger configuration
βββ user-service/ # User management + Document + Graph + Webhook
β βββ controller/
β βββ service/
β βββ dto/
β βββ resources/
βββ order-service/ # Order management (to be implemented)
βββ payment-service/ # Payment processing (to be implemented)
- Java: JDK 17 or 21
- Maven: 3.6+
- IntelliJ IDEA: 2023+ (Community or Ultimate)
- Optional: Microsoft Azure account (for Graph API)
- Optional: SMTP server credentials (for email functionality)
multi-module-api/
βββ pom.xml # Root POM with dependency management
βββ common/
β βββ pom.xml
β βββ src/main/java/com/example/common/
β βββ response/ApiResponse.java
β βββ exception/
β β βββ GlobalExceptionHandler.java
β β βββ BusinessException.java
β β βββ ResourceNotFoundException.java
β β βββ UnauthorizedException.java
β βββ security/JwtTokenUtil.java
β βββ config/SwaggerConfig.java
βββ user-service/
β βββ pom.xml
β βββ src/main/
β βββ java/com/example/userservice/
β β βββ UserServiceApplication.java
β β βββ controller/
β β β βββ AuthController.java
β β β βββ UserController.java
β β β βββ DocumentController.java
β β β βββ GraphApiController.java
β β β βββ WebhookController.java
β β βββ service/
β β β βββ UserService.java
β β β βββ DocumentService.java
β β β βββ GraphApiService.java
β β β βββ WebhookService.java
β β βββ dto/
β β βββ UserDto.java
β β βββ InvoiceDto.java
β β βββ DocumentMetadataDto.java
β β βββ WebhookRegistrationDto.java
β β βββ WebhookPayloadDto.java
β β βββ GraphUserDto.java
β β βββ EmailMessageDto.java
β βββ resources/
β βββ application.yml
β βββ application-uat.yml
β βββ application-prod.yml
βββ order-service/
β βββ pom.xml
βββ payment-service/
βββ pom.xml
- Open IntelliJ IDEA
- Select File β Open
- Navigate to the
multi-module-apifolder - Click Open
- IntelliJ will detect Maven project and import automatically
- Go to File β Project Structure
- Under Project Settings β Project
- Set SDK to Java 17 or 21
- Set Language Level to 17 or 21
- Click Apply and OK
- Go to File β Settings (Windows/Linux) or IntelliJ IDEA β Preferences (Mac)
- Navigate to Build, Execution, Deployment β Compiler β Annotation Processors
- Check Enable annotation processing
- Click Apply and OK
- Go to File β Settings β Plugins
- Search for "Lombok"
- Install the Lombok plugin
- Restart IntelliJ IDEA
- Open Maven panel (View β Tool Windows β Maven)
- Expand multi-module-api
- Run Lifecycle β clean
- Run Lifecycle β install
The application supports three profiles:
# No profile specified - uses application.ymljava -jar -Dspring.profiles.active=uat user-service.jar- β Swagger UI: ENABLED
- β Token authentication: REQUIRED
- β Public access: YES (with token)
java -jar -Dspring.profiles.active=prod user-service.jar- β Swagger UI: DISABLED
- β API documentation: NOT ACCESSIBLE
- β Security: MAXIMUM
Update application.yml:
spring:
mail:
host: smtp.gmail.com
port: 587
username: your-email@gmail.com
password: your-app-password # Use App Password for Gmail
properties:
mail:
smtp:
auth: true
starttls:
enable: trueFor Gmail:
- Enable 2-Factor Authentication
- Generate App Password: https://myaccount.google.com/apppasswords
- Use the generated password in configuration
To enable Graph API features:
-
Register Application in Azure AD:
- Go to https://portal.azure.com
- Navigate to Azure Active Directory β App registrations
- Click "New registration"
- Note: Client ID, Tenant ID
-
Generate Client Secret:
- In your app registration β Certificates & secrets
- Create new client secret
- Copy the secret value
-
Configure API Permissions:
- In your app registration β API permissions
- Add Microsoft Graph permissions:
User.ReadUser.Read.AllMail.SendCalendars.ReadFiles.Read
- Grant admin consent
-
Update Configuration:
microsoft:
graph:
client-id: your-client-id
tenant-id: your-tenant-id
client-secret: your-client-secret- Uncomment Graph SDK Code:
- Open
GraphApiService.java - Uncomment the Graph SDK initialization and API calls
- Open
Update JWT secret (especially for production):
jwt:
secret: your-very-long-and-secure-secret-key-here
expiration: 86400000 # 24 hours- Open
UserServiceApplication.java - Click the green play button next to the class
- Or right-click β Run 'UserServiceApplication'
To run with specific profile:
- Click Run β Edit Configurations
- Select your run configuration
- In VM options, add:
-Dspring.profiles.active=uator-Dspring.profiles.active=prod - Click Apply and OK
- Run the configuration
# Default profile (development)
cd user-service
mvn spring-boot:run
# UAT profile (Swagger enabled)
mvn spring-boot:run -Dspring-boot.run.profiles=uat
# Production profile (Swagger disabled)
mvn spring-boot:run -Dspring-boot.run.profiles=prod# Build
cd multi-module-api
mvn clean package
# Run with specific profile
java -jar user-service/target/user-service-1.0.0.jar --spring.profiles.active=uat- Start application with UAT profile:
-Dspring.profiles.active=uat - Open browser: http://localhost:8080/swagger-ui.html
- You'll see grouped API documentation for all modules
- Swagger is completely disabled
- Attempting to access
/swagger-ui.htmlwill return 404 - This is intentional for security
The documentation is organized into groups:
- 0-authentication: Login and token generation
- 1-user-service: User CRUD operations
- 2-order-service: Order management (placeholder)
- 3-payment-service: Payment processing (placeholder)
- 4-webhooks: Webhook registration and events
- 5-graph-api: Microsoft Graph integrations
- all-apis: Combined view of all endpoints
-
Get Token:
- Open Swagger UI
- Go to 0-authentication group
- Expand
POST /api/auth/login - Click Try it out
- Use credentials:
{ "username": "admin", "password": "admin123" } - Click Execute
- Copy the
accessTokenfrom response
-
Authorize:
- Click the Authorize button (lock icon) at top right
- Paste the token in the Value field
- Click Authorize
- Click Close
-
Test APIs:
- Now you can test any API endpoint
- The token will be automatically included in requests
# Get JWT Token
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "admin123"
}'Response:
{
"success": true,
"message": "Login successful",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresAt": 1704067200000,
"username": "admin"
},
"timestamp": "2024-01-15T10:30:00"
}# Create User
curl -X POST http://localhost:8080/api/user \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+1234567890"
}'
# Get All Users
curl -X GET http://localhost:8080/api/user \
-H "Authorization: Bearer YOUR_TOKEN"
# Get User by ID
curl -X GET http://localhost:8080/api/user/1 \
-H "Authorization: Bearer YOUR_TOKEN"# Upload Document
curl -X POST http://localhost:8080/api/document/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@/path/to/your/document.pdf" \
-F "documentType=BILL" \
-F "notes=January utility bill"# Generate Invoice PDF
curl -X POST http://localhost:8080/api/document/generate/invoice \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"invoiceNumber": "INV-2024-001",
"invoiceDate": "2024-01-15",
"dueDate": "2024-02-15",
"sellerName": "ABC Corporation",
"sellerAddress": "123 Business St, City, Country",
"sellerEmail": "billing@abccorp.com",
"customerName": "John Doe",
"customerEmail": "john.doe@example.com",
"items": [
{
"description": "Consulting Services",
"quantity": 10,
"unitPrice": 100.00,
"unit": "hours",
"lineTotal": 1000.00
}
],
"subtotal": 1000.00,
"taxRate": 10.0,
"taxAmount": 100.00,
"totalAmount": 1100.00,
"currency": "USD",
"notes": "Thank you for your business!"
}' \
--output invoice.pdf# Register Webhook
curl -X POST http://localhost:8080/api/webhook/register \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook/receiver",
"events": ["user.created", "user.updated", "order.completed"],
"name": "My Webhook",
"description": "Receives user and order events"
}'# Send Event to Webhook (simulating external system)
curl -X POST http://localhost:8080/api/webhook/events/webhook-12345 \
-H "Content-Type: application/json" \
-H "X-Webhook-Signature: YOUR_SIGNATURE" \
-d '{
"event_type": "user.created",
"user_id": "123",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"email": "newuser@example.com",
"name": "New User"
}
}'- ApiResponse: Standard response wrapper
- GlobalExceptionHandler: Centralized exception handling
- JwtTokenUtil: JWT token generation and validation
- SwaggerConfig: API documentation configuration
- Custom Exceptions: BusinessException, ResourceNotFoundException, UnauthorizedException
- User Management: CRUD operations
- Document Upload: Multi-part file upload
- Invoice Generation: PDF creation with iText
- Email Service: Send generated documents
- Microsoft Graph API: Office 365 integration
- Webhook Support: Event-driven architecture
- To be implemented with similar structure
- Suggested endpoints:
POST /api/order- Create orderGET /api/order/{id}- Get orderPUT /api/order/{id}- Update orderGET /api/order- List orders
- To be implemented with similar structure
- Suggested endpoints:
POST /api/payment- Process paymentGET /api/payment/{id}- Get payment statusPOST /api/payment/refund- Refund payment
- JWT Authentication: All APIs (except login) require valid JWT token
- Token-Based Swagger Access: Swagger UI requires authentication in UAT
- Environment-Based Controls: Documentation disabled in production
- Webhook Signature Validation: HMAC-SHA256 signature verification
- Input Validation: Jakarta validation on all DTOs
- CORS Configuration: Can be configured per environment
- Disable Swagger: Ensure
spring.profiles.active=prod - Use Strong JWT Secret: At least 64 characters
- Configure SSL: Enable HTTPS
- Use Environment Variables: Don't hardcode secrets
- Configure Proper SMTP: Use production mail server
- Set Up Monitoring: Use Spring Boot Actuator
- Database Integration: Replace in-memory storage with actual database
# UAT - Swagger ENABLED
springdoc:
api-docs:
enabled: true
swagger-ui:
enabled: true
# PROD - Swagger DISABLED
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: falseLogin Credentials (Change in production):
- Username:
admin - Password:
admin123
Solution: Enable annotation processing in IntelliJ (see Step 3 in IntelliJ Setup)
Solution:
- Check if running with correct profile
- UAT profile: Swagger is enabled
- PROD profile: Swagger is disabled (intended behavior)
Solution: Check spring.servlet.multipart.max-file-size configuration
Solution:
- Verify SMTP credentials
- For Gmail, use App Password instead of regular password
- Check firewall settings
Solution:
- Verify Azure AD app registration
- Check API permissions are granted
- Uncomment Graph SDK code in
GraphApiService.java - Verify credentials in
application.yml
This project is created for demonstration purposes.
For issues or questions:
- Check this README
- Review application logs
- Check Swagger documentation (in UAT environment)
Created with β€οΈ for demonstrating Spring Boot best practices