simplelink/API.md
2025-01-25 03:16:35 -05:00

321 lines
5.9 KiB
Markdown

# Link Shortener API Documentation
## Base URL
`http://localhost:8080`
## Authentication
The API uses JWT tokens for authentication. Include the token in the Authorization header:
```
Authorization: Bearer <your_token>
```
### Register
Create a new user account.
```bash
POST /api/auth/register
```
Request Body:
```json
{
"email": string, // Required: Valid email address
"password": string // Required: Password
}
```
Example:
```bash
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password"
}'
```
Response (200 OK):
```json
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"email": "user@example.com"
}
}
```
### Login
Authenticate and receive a JWT token.
```bash
POST /api/auth/login
```
Request Body:
```json
{
"email": string, // Required: Registered email address
"password": string // Required: Password
}
```
Example:
```bash
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password"
}'
```
Response (200 OK):
```json
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"email": "user@example.com"
}
}
```
## Protected Endpoints
### Health Check
Check if the service and database are running.
```bash
GET /health
```
Example:
```bash
curl http://localhost:8080/health
```
Response (200 OK):
```json
"Healthy"
```
Response (503 Service Unavailable):
```json
"Database unavailable"
```
### Create Short URL
Create a new shortened URL with optional custom code. Requires authentication.
```bash
POST /api/shorten
```
Request Body:
```json
{
"url": string, // Required: The URL to shorten
"custom_code": string, // Optional: Custom short code
"source": string // Optional: Source of the request
}
```
Examples:
1. Create with auto-generated code:
```bash
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"url": "https://example.com",
"source": "curl-test"
}'
```
Response (201 Created):
```json
{
"id": 1,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "Xa7Bc9",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 0
}
```
2. Create with custom code:
```bash
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"url": "https://example.com",
"custom_code": "example",
"source": "curl-test"
}'
```
Response (201 Created):
```json
{
"id": 2,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "example",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 0
}
```
Error Responses:
Invalid URL (400 Bad Request):
```json
{
"error": "URL must start with http:// or https://"
}
```
Custom code taken (400 Bad Request):
```json
{
"error": "Custom code already taken"
}
```
Invalid custom code (400 Bad Request):
```json
{
"error": "Custom code must be 1-32 characters long and contain only letters, numbers, underscores, and hyphens"
}
```
Unauthorized (401 Unauthorized):
```json
{
"error": "Unauthorized"
}
```
### Get All Links
Retrieve all shortened URLs for the authenticated user.
```bash
GET /api/links
```
Example:
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/links
```
Response (200 OK):
```json
[
{
"id": 1,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "Xa7Bc9",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 5
},
{
"id": 2,
"user_id": 1,
"original_url": "https://example.org",
"short_code": "example",
"created_at": "2024-03-01T12:35:00Z",
"clicks": 3
}
]
```
### Redirect to Original URL
Use the shortened URL to redirect to the original URL. Source tracking via query parameter is supported.
```bash
GET /{short_code}?source={source}
```
Example:
```bash
curl -i http://localhost:8080/example?source=email
```
Response (307 Temporary Redirect):
```http
HTTP/1.1 307 Temporary Redirect
Location: https://example.com
```
Error Response (404 Not Found):
```json
{
"error": "Not found"
}
```
## Custom Code Rules
1. Length: 1-32 characters
2. Allowed characters: letters, numbers, underscores, and hyphens
3. Case-sensitive
4. Cannot use reserved words: ["api", "health", "admin", "static", "assets"]
## Rate Limiting
Currently, no rate limiting is implemented.
## Notes
1. All timestamps are in UTC
2. Click counts are incremented on successful redirects
3. Source tracking is supported both at link creation and during redirection via query parameter
4. Custom codes are case-sensitive
5. URLs must include protocol (http:// or https://)
6. All create/read operations require authentication
7. Users can only see and manage their own links
## Error Codes
- 200: Success
- 201: Created
- 307: Temporary Redirect
- 400: Bad Request (invalid input)
- 401: Unauthorized (missing or invalid token)
- 404: Not Found
- 503: Service Unavailable
## Database Schema
```sql
-- Users table for authentication
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL
);
-- Links table with user association
CREATE TABLE links (
id SERIAL PRIMARY KEY,
original_url TEXT NOT NULL,
short_code VARCHAR(8) NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
clicks BIGINT NOT NULL DEFAULT 0,
user_id INTEGER REFERENCES users(id)
);
-- Click tracking with source information
CREATE TABLE clicks (
id SERIAL PRIMARY KEY,
link_id INTEGER REFERENCES links(id),
source TEXT,
query_source TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_short_code ON links(short_code);
CREATE INDEX idx_user_id ON links(user_id);
CREATE INDEX idx_link_id ON clicks(link_id);
```