Skip to content

✅REST API developed with Spring Boot to manage users and send email notifications using Mailpit as an SMTP server. It includes integration with PostgreSQL and is fully pluggable for easy development and testing. The project also supports audit logging, Prometheus monitoring, Grafana dashboards, and Swagger/OpenAPI documentation for streamlined obse

Notifications You must be signed in to change notification settings

andresWeitzel/email-api-service-MailPit

Repository files navigation

Email API Service



User Management Email API (status-completed)

A comprehensive REST API developed with Spring Boot to manage users and send email notifications using Mailpit as the SMTP server. It integrates seamlessly with PostgreSQL for data storage, and includes features for audit logging, Prometheus monitoring, Grafana dashboards, and automatic API documentation with Swagger/OpenAPI.

Sections

1. Features
  • User Management: Complete CRUD operations for user management
  • Email Notifications: Automated email sending for user events
  • Audit Logging: Comprehensive tracking of all system actions
  • Monitoring: Real-time metrics and health checks
  • API Documentation: Interactive Swagger UI for API exploration
  • Containerization: Easy deployment with Docker
  • Database Integration: Robust PostgreSQL integration
  • Metrics Visualization: Grafana dashboards for system monitoring
2. Requirements
  • Java 17 or higher
  • Docker and Docker Compose
  • Maven for building the project
  • PostgreSQL (if running without Docker)
  • Mailpit (if running without Docker)
3. Technologies and Dependencies
  • Spring Boot: Core framework for building Java applications
  • Spring Boot Starter Web: For creating RESTful web applications
  • Spring Boot Starter Mail: For handling emails
  • Spring Boot Starter Data JPA: For database operations
  • Spring Boot Starter Actuator: For monitoring and metrics
  • PostgreSQL: Database for data persistence
  • Mailpit: SMTP server for local email testing
  • Docker & Docker Compose: For containerization and orchestration
  • Prometheus: For metrics collection
  • Grafana: For metrics visualization
  • Swagger/OpenAPI: For API documentation
  • Lombok: For reducing boilerplate code
  • JUnit: For unit testing
4. Configuration and Execution

Repository Clone

git clone https://github.com/andresWeitzel/email-api-service-MailPit
cd email-api-service-MailPit

Docker Compose Setup for Development

  • Before building and running the containers, make sure you have Docker running (for Windows, use Docker Desktop)
  • Once installed, make sure Docker is running
docker --version

Important: Check that no other service (ej:postgres) is running as a daemon on the system, otherwise a connection problem will occur on the port.

  • Once Docker is running, you can build and deploy the containers with docker compose (This command is only needed once to build).
  • The container for Mailpit and Postgres will be created.
docker-compose up --build
  • After creating the containers with Docker Compose, each time we are going to start the containers we will use the following command, otherwise we will run it from Docker Desktop. Start the environment in development mode. Every time you want to run the app in development, you won't need to compile the jar. Simply run the following command:
docker-compose up
  • Another option is to launch the containers from Docker Desktop.
  • Run the application
mvn spring-boot:run
5. Project Structure
email-api-service-MailPit/
├── src/
│   ├── main/
│   │   ├── java/com/microservice/
│   │   │   ├── config/           # Configuration classes
│   │   │   ├── controller/       # REST controllers
│   │   │   ├── dto/             # Data Transfer Objects
│   │   │   ├── exception/       # Exception handlers
│   │   │   ├── model/           # Entity models
│   │   │   ├── repository/      # Data access layer
│   │   │   ├── service/         # Business logic
│   │   │   └── EmailApiMailpitApplication.java
│   │   └── resources/
│   │       ├── application.yml  # Application configuration
│   │       └── static/          # Static resources
│   └── test/                    # Test classes
├── docker-compose.yml           # Docker orchestration
├── Dockerfile                   # Application container
├── pom.xml                      # Maven dependencies
└── README.md                    # Project documentation

Key Components

  • Controllers: Handle HTTP requests and responses
  • Services: Implement business logic
  • Repositories: Data access layer
  • DTOs: Data transfer objects for API communication
  • Models: JPA entities for database mapping
  • Config: Application configuration classes
  • Exceptions: Custom exception handling
6. Processing Flow
  1. User Management:

    • Create, read, update, and delete user operations
    • Email notifications sent automatically for user events
    • Audit logging for all user-related actions
  2. Email Processing:

    • Email service integration with Mailpit SMTP server
    • Template-based email generation
    • Email delivery status tracking
  3. Audit Logging:

    • Comprehensive tracking of all system actions
    • Filtering capabilities by entity, action, username, and details
    • Historical data retention
  4. Monitoring & Observability:

    • Real-time health checks via Spring Boot Actuator
    • Metrics collection with Prometheus
    • Dashboard visualization with Grafana
7. API Examples

User Management Examples

Create User

curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john.doe@example.com"
  }'

Required Fields:

  • name: String (mandatory) - The name of the user
  • email: String (mandatory) - Valid email format

Response Examples:

Success Response (200):

{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Error Responses:

Validation Error (400):

{
  "errors": {
    "name": "The name is mandatory"
  },
  "timestamp": "2025-07-14T17:21:59.3410006",
  "status": 400
}

Invalid Email Format (400):

{
  "errors": {
    "email": "The email is invalid"
  },
  "timestamp": "2025-07-14T17:21:59.3410006",
  "status": 400
}

Duplicate Email Error (400):

{
  "errors": "Email is already in use: The email john.doe@exampletest.com already exists.",
  "timestamp": "2025-07-14T17:30:37.1875171",
  "status": 400
}

📧 Mailpit Email (after successful creation):

From: noreply@email-api-service.com
To: john.doe@example.com
Subject: Account register Notification

Hello John Doe,

Thank you for registering with us!

Get All Users

curl -X GET http://localhost:8080/api/v1/users

Response Examples:

Success Response (200):

{
  "content": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "john.doe@example.com"
    },
    {
      "id": 2,
      "name": "Jane Smith",
      "email": "jane.smith@example.com"
    }
  ],
  "pageable": {
    "sort": {
      "empty": false,
      "sorted": true,
      "unsorted": false
    },
    "offset": 0,
    "pageNumber": 0,
    "pageSize": 30,
    "paged": true,
    "unpaged": false
  },
  "totalElements": 2,
  "totalPages": 1,
  "last": true,
  "size": 30,
  "number": 0,
  "sort": {
    "empty": false,
    "sorted": true,
    "unsorted": false
  },
  "numberOfElements": 2,
  "first": true,
  "empty": false
}

Update User

curl -X PUT http://localhost:8080/api/v1/users/1 \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe Updated",
    "email": "john.updated@example.com"
  }'

Response Examples:

Success Response (200):

{
  "id": 1,
  "name": "John Doe Updated",
  "email": "john.updated@example.com"
}

Error Responses:

User Not Found (404):

{
  "errors": "User not found with id: 999",
  "timestamp": "2025-07-14T17:45:12.9876543",
  "status": 404
}

Validation Error (400):

{
  "errors": {
    "email": "The email is invalid"
  },
  "timestamp": "2025-07-14T17:45:12.9876543",
  "status": 400
}

📧 Mailpit Email (after successful update):

From: noreply@email-api-service.com
To: john.updated@example.com
Subject: Account Update Notification

Hello John Doe Updated,

Your account has been successfully updated.

Delete User

curl -X DELETE http://localhost:8080/api/v1/users/1

Response Examples:

Success Response (200):

{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Error Response:

User Not Found (404):

{
  "errors": "User not found with id: 999",
  "timestamp": "2025-07-14T17:50:25.1234567",
  "status": 404
}

📧 Mailpit Email (after successful deletion):

From: noreply@email-api-service.com
To: john.doe@example.com
Subject: Account Deletion Notification

Hello John Doe,

Your account has been successfully deleted.

Get User by ID

curl -X GET http://localhost:8080/api/v1/users/1

Response Examples:

Success Response (200):

{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com",
  "createdAt": "2025-07-14T17:30:37.1875171",
  "updatedAt": "2025-07-14T17:30:37.1875171"
}

Error Response:

User Not Found (404):

{
  "errors": "User not found with id: 999",
  "timestamp": "2025-07-14T17:50:25.1234567",
  "status": 404
}

Audit Log Examples

Create Audit Log

curl -X POST http://localhost:8080/api/v1/audit-log \
  -H "Content-Type: application/json" \
  -d '{
    "entity": "User",
    "action": "CREATE",
    "username": "admin_user",
    "details": "Created new user account with email john.doe@example.com"
  }'

Audit Log Fields:

  • entity: String - The entity being audited (e.g., "User")
  • action: String - The action performed (e.g., "CREATE", "UPDATE", "DELETE")
  • username: String - The username of the person performing the action
  • details: String - Detailed description of the action
  • timestamp: LocalDateTime (optional) - When the action occurred

Response Examples:

Success Response (200):

{
  "message": "Audit log created successfully"
}

Update Audit Log

curl -X PUT http://localhost:8080/api/v1/audit-log/1 \
  -H "Content-Type: application/json" \
  -d '{
    "entity": "User",
    "action": "UPDATE",
    "username": "admin_user",
    "details": "Updated user account information"
  }'

Response Examples:

Success Response (200):

{
  "id": 1,
  "entity": "User",
  "action": "UPDATE",
  "username": "admin_user",
  "details": "Updated user account information",
  "timestamp": "2025-07-14T17:55:42.6543210"
}

Error Response:

Audit Log Not Found (404):

{
  "errors": "Audit log not found with id: 999",
  "timestamp": "2025-07-14T17:55:42.6543210",
  "status": 404
}

Filter Audit Logs

# Filter by entity
curl -X GET "http://localhost:8080/api/v1/audit-log/entity?entity=User"

# Filter by action
curl -X GET "http://localhost:8080/api/v1/audit-log/action?action=CREATE"

# Filter by username
curl -X GET "http://localhost:8080/api/v1/audit-log/username?username=admin_user"

# Filter by details
curl -X GET "http://localhost:8080/api/v1/audit-log/details?details=Created+new+user"

Response Examples:

Success Response (200) - Filtered Results:

{
  "content": [
    {
      "id": 1,
      "entity": "User",
      "action": "CREATE",
      "username": "admin_user",
      "details": "Created new user account with email john.doe@example.com",
      "timestamp": "2025-07-14T17:30:37.1875171"
    },
    {
      "id": 3,
      "entity": "User",
      "action": "CREATE",
      "username": "admin_user",
      "details": "Created new user account with email jane.smith@example.com",
      "timestamp": "2025-07-14T17:35:22.1234567"
    }
  ],
  "pageable": {
    "sort": {
      "empty": false,
      "sorted": true,
      "unsorted": false
    },
    "offset": 0,
    "pageNumber": 0,
    "pageSize": 30,
    "paged": true,
    "unpaged": false
  },
  "totalElements": 2,
  "totalPages": 1,
  "last": true,
  "size": 30,
  "number": 0,
  "sort": {
    "empty": false,
    "sorted": true,
    "unsorted": false
  },
  "numberOfElements": 2,
  "first": true,
  "empty": false
}

Empty Results Response (200):

{
  "content": [],
  "pageable": {
    "sort": {
      "empty": false,
      "sorted": true,
      "unsorted": false
    },
    "offset": 0,
    "pageNumber": 0,
    "pageSize": 30,
    "paged": true,
    "unpaged": false
  },
  "totalElements": 0,
  "totalPages": 0,
  "last": true,
  "size": 30,
  "number": 0,
  "sort": {
    "empty": false,
    "sorted": true,
    "unsorted": false
  },
  "numberOfElements": 0,
  "first": true,
  "empty": true
}

HTTP Status Codes

Common Response Status Codes:

  • 200 OK: Request successful
  • 201 Created: Resource created successfully
  • 400 Bad Request: Validation error or invalid data
  • 404 Not Found: Resource not found
  • 409 Conflict: Resource conflict (e.g., duplicate email)
  • 500 Internal Server Error: Server error

Step-by-Step Testing Guide

1. Start the Application:

docker-compose up

2. Create a User:

curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john.doe@example.com"
  }'

3. Check Mailpit for Email:

4. Get All Users:

curl -X GET http://localhost:8080/api/v1/users

5. Update the User:

curl -X PUT http://localhost:8080/api/v1/users/1 \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe Updated",
    "email": "john.updated@example.com"
  }'

6. Check Mailpit Again:

7. Delete the User:

curl -X DELETE http://localhost:8080/api/v1/users/1

8. Final Mailpit Check:


Common Error Scenarios

Try these to test error handling:

1. Create User with Missing Name:

curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john.doe@example.com"
  }'

Expected Response:

{
  "errors": {
    "name": "The name is mandatory"
  },
  "timestamp": "2025-07-14T17:21:59.3410006",
  "status": 400
}

2. Create User with Invalid Email:

curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "invalid-email"
  }'

Expected Response:

{
  "errors": {
    "email": "The email is invalid"
  },
  "timestamp": "2025-07-14T17:21:59.3410006",
  "status": 400
}

3. Create User with Duplicate Email:

# First, create a user
curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john.doe@example.com"
  }'

# Then try to create another user with the same email
curl -X POST http://localhost:8080/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "email": "john.doe@example.com"
  }'

Expected Response:

{
  "errors": "Email is already in use: The email john.doe@example.com already exists.",
  "timestamp": "2025-07-14T17:30:37.1875171",
  "status": 400
}

📧 Mailpit Email (NO email sent for duplicate email error):

No email will be sent to Mailpit when there's a duplicate email error.
The user creation fails before the email service is called.

4. Get Non-existent User:

curl -X GET http://localhost:8080/api/v1/users/999

Expected Response:

{
  "errors": "User not found with id: 999",
  "timestamp": "2025-07-14T17:50:25.1234567",
  "status": 404
}

📧 Mailpit Email (NO email sent for not found error):

No email will be sent to Mailpit when there's a "not found" error.
The operation fails before the email service is called.

📧 Email Notification Summary

Emails are sent to Mailpit ONLY for successful operations:

CREATE User → Welcome email sent ✅ UPDATE User → Update notification email sent
DELETE User → Deletion confirmation email sent ❌ Validation Errors → No email sent ❌ Duplicate Email → No email sent ❌ User Not Found → No email sent


Testing de Endpoints de Servicios Dockerizados

Mailpit Email Examples

When you access Mailpit at http://localhost:8025, you'll see emails like these:

User Creation Email

From: noreply@email-api-service.com
To: john.doe@example.com
Subject: Welcome to Our Service!

Dear John Doe,

Welcome to our service! Your account has been successfully created.

Account Details:
- Name: John Doe
- Email: john.doe@example.com
- Account ID: 1

Thank you for joining us!

Best regards,
The Email API Service Team

User Update Email

From: noreply@email-api-service.com
To: john.updated@example.com
Subject: Your Account Has Been Updated

Dear John Doe Updated,

Your account information has been successfully updated.

Updated Details:
- Name: John Doe Updated
- Email: john.updated@example.com
- Account ID: 1

If you didn't request this change, please contact support immediately.

Best regards,
The Email API Service Team

User Deletion Email

From: noreply@email-api-service.com
To: john.doe@example.com
Subject: Account Deletion Confirmation

Dear John Doe,

Your account has been successfully deleted from our system.

Account Details:
- Name: John Doe
- Email: john.doe@example.com
- Account ID: 1

All your data has been permanently removed.

Best regards,
The Email API Service Team

Mailpit Features:

  • Email Preview: View HTML and text versions of emails
  • Email Details: See headers, attachments, and metadata
  • Search: Filter emails by sender, recipient, or content
  • Export: Download emails for testing purposes
  • Real-time: Emails appear instantly when sent by the API
8. Implemented Validations
  • User Data Validation:

    • Email format validation
    • Username uniqueness check
    • Required field validation
    • Data integrity constraints
  • Email Validation:

    • SMTP server connectivity
    • Email format verification
    • Delivery status tracking
  • Database Validation:

    • Connection health checks
    • Transaction rollback on errors
    • Data consistency validation
  • API Validation:

    • Request payload validation
    • HTTP status code handling
    • Error response formatting
9. Monitoring & Reports

The system provides comprehensive monitoring and reporting capabilities:

  • Health Checks: Application health monitoring via Spring Boot Actuator
  • Metrics Collection: Prometheus metrics for performance monitoring
  • Dashboard Visualization: Grafana dashboards for system monitoring
  • Audit Reports: Comprehensive audit trail for compliance
  • Email Delivery Reports: Email sending status and delivery tracking
10. Contributing
  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request
11. License

This project is under the MIT License - see the LICENSE file for details.

About

✅REST API developed with Spring Boot to manage users and send email notifications using Mailpit as an SMTP server. It includes integration with PostgreSQL and is fully pluggable for easy development and testing. The project also supports audit logging, Prometheus monitoring, Grafana dashboards, and Swagger/OpenAPI documentation for streamlined obse

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published