A Spring Boot REST API service that converts long URLs into compact, manageable short URLs with full CRUD operations and persistence.
- URL Shortening: Convert long URLs to short 6-character alphanumeric codes
- URL Retrieval: Retrieve original URLs from short URLs with automatic redirection
- Duplicate Handling: Same long URL always produces the same short URL
- URL Validation: Validates URL format before processing
- Collision Prevention: Handles potential collisions by increasing URL length if needed
- CRUD Operations: Create, read, update, and delete URL mappings
- Enable/Disable: Enable or disable URL mappings without deletion
- Statistics: Get usage statistics and mapping counts
- Persistence: H2 database with file-based storage
- Health Checks: Built-in health monitoring with Spring Actuator
- Docker Support: Full containerization with Docker and Docker Compose
- Framework: Spring Boot 3.2.0
- Language: Java 17
- Database: H2 (file-based)
- Build Tool: Maven
- Containerization: Docker & Docker Compose
- Validation: Spring Validation
- Monitoring: Spring Actuator
- Java 17 or higher
- Maven 3.6+
- Docker & Docker Compose (for containerized deployment)
-
Clone the repository
git clone <repository-url> cd DesafioMeli
-
Build the application
mvn clean package
-
Run the application
java -jar target/url-shortener-api-1.0.0.jar
-
Access the application
- API Base URL:
http://localhost:8080 - H2 Console:
http://localhost:8080/h2-console - Health Check:
http://localhost:8080/actuator/health
- API Base URL:
-
Build and run with Docker Compose
docker compose up --build
-
Or build and run manually
# Build the image docker build -t url-shortener-api . # Run the container docker run -p 8080:8080 url-shortener-api
http://localhost:8080
POST /shorten
Creates a new short URL or returns existing one if the long URL was already shortened.
Request Body:
{
"longUrl": "https://www.example.com/very-long-url-with-many-parameters"
}Response:
{
"shortUrl": "aB3x9K",
"longUrl": "https://www.example.com/very-long-url-with-many-parameters",
"isNew": true
}Status Codes:
200 OK: URL shortened successfully400 Bad Request: Invalid URL format
GET /{shortUrl}
Redirects to the original long URL.
Parameters:
shortUrl(path): The short URL code
Response:
302 Found: Redirects to original URL404 Not Found: Short URL doesn't exist or is disabled
GET /
Returns all URL mappings in the system.
Response:
[
{
"shortUrl": "aB3x9K",
"longUrl": "https://www.example.com/very-long-url",
"enabled": true
},
{
"shortUrl": "mN7pQ2",
"longUrl": "https://github.com/features/actions",
"enabled": true
}
]PUT /{shortUrl}
Updates the long URL for an existing short URL.
Parameters:
shortUrl(path): The short URL to update
Request Body:
{
"newLongUrl": "https://www.new-example.com/updated-url"
}Status Codes:
200 OK: URL updated successfully400 Bad Request: Invalid URL format404 Not Found: Short URL doesn't exist
PUT /{shortUrl}/enable
Enables or disables a URL mapping without deleting it.
Parameters:
shortUrl(path): The short URL to enable/disable
Request Body:
{
"enabled": false
}Status Codes:
200 OK: Status updated successfully404 Not Found: Short URL doesn't exist
GET /stats
Returns statistics about the URL shortener.
Response:
{
"totalMappings": 42
}GET /{shortUrl}/exists
Checks if a short URL exists in the system.
Parameters:
shortUrl(path): The short URL to check
Response:
{
"exists": true
}# Build the Docker image
docker build -t url-shortener-api .
# Build with custom tag
docker build -t url-shortener-api:v1.0.0 .# Run the container
docker run -p 8080:8080 url-shortener-api
# Run with custom port mapping
docker run -p 9000:8080 url-shortener-api
# Run with volume for data persistence
docker run -p 8080:8080 -v url-data:/app/data url-shortener-apiThe project includes a docker-compose.yml file for easy deployment:
# Start all services
docker compose up
# Start in background
docker compose up -d
# Rebuild and start
docker compose up --build
# Stop services
docker compose down
# Stop and remove volumes
docker compose down -vThe Docker setup includes:
- Multi-stage build for optimized image size
- Health checks with curl
- Volume persistence for H2 database
- Environment variables for JVM tuning
- Network isolation with custom bridge network
| Variable | Default | Description |
|---|---|---|
JAVA_OPTS |
-Xmx512m -Xms256m |
JVM memory settings |
SPRING_PROFILES_ACTIVE |
docker |
Spring profile for Docker |
The application uses H2 database with file-based persistence:
- Database Type: H2 (in-memory/file)
- Storage: File-based (
./data/urlshortener) - Console: Available at
/h2-console - Credentials:
- Username:
sa - Password:
password
- Username:
CREATE TABLE url_mapping_entity (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
short_url VARCHAR(255) NOT NULL UNIQUE,
long_url TEXT NOT NULL,
enabled BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Key configuration options in application.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:h2:file:./data/urlshortener
username: sa
password: password
jpa:
hibernate:
ddl-auto: update
show-sql: true
management:
endpoints:
web:
exposure:
include: health,info,metrics- Default: Standard development configuration
- Docker: Optimized for containerized deployment
- Endpoint:
/actuator/health - Docker Health Check: Built into Dockerfile
- Response: JSON with application status
Available metrics at /actuator/metrics:
- HTTP request metrics
- JVM metrics
- Database connection metrics
# Run tests
mvn test
# Run with coverage
mvn test jacoco:reportsrc/
βββ main/
β βββ java/
β β βββ com/example/urlshortener/
β β βββ controller/ # REST controllers
β β βββ dto/ # Data transfer objects
β β βββ entity/ # JPA entities
β β βββ repository/ # Data access layer
β β βββ service/ # Business logic
β β βββ UrlShortenerApplication.java
β βββ resources/
β βββ application.yml
β βββ application-docker.yml
βββ test/
βββ java/
βββ com/example/urlshortener/
βββ UrlShortenerApplicationTests.java
- Database: Consider using PostgreSQL or MySQL for production
- Security: Implement authentication and authorization
- Rate Limiting: Add rate limiting to prevent abuse
- Logging: Configure proper logging and monitoring
- SSL/TLS: Use HTTPS in production
- Caching: Add Redis for caching frequently accessed URLs
# Database configuration
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/urlshortener
SPRING_DATASOURCE_USERNAME=dbuser
SPRING_DATASOURCE_PASSWORD=dbpassword
# JVM settings
JAVA_OPTS=-Xmx2g -Xms1g
# Application settings
SERVER_PORT=8080