Skip to content

Latest commit

 

History

History
321 lines (273 loc) · 5.9 KB

API.md

File metadata and controls

321 lines (273 loc) · 5.9 KB

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.

POST /api/auth/register

Request Body:

{
  "email": string,     // Required: Valid email address
  "password": string   // Required: Password
}

Example:

curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "your_password"
  }'

Response (200 OK):

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "user": {
    "id": 1,
    "email": "[email protected]"
  }
}

Login

Authenticate and receive a JWT token.

POST /api/auth/login

Request Body:

{
  "email": string,     // Required: Registered email address
  "password": string   // Required: Password
}

Example:

curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "your_password"
  }'

Response (200 OK):

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "user": {
    "id": 1,
    "email": "[email protected]"
  }
}

Protected Endpoints

Health Check

Check if the service and database are running.

GET /health

Example:

curl http://localhost:8080/health

Response (200 OK):

"Healthy"

Response (503 Service Unavailable):

"Database unavailable"

Create Short URL

Create a new shortened URL with optional custom code. Requires authentication.

POST /api/shorten

Request Body:

{
  "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:
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):

{
  "id": 1,
  "user_id": 1,
  "original_url": "https://example.com",
  "short_code": "Xa7Bc9",
  "created_at": "2024-03-01T12:34:56Z",
  "clicks": 0
}
  1. Create with custom code:
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):

{
  "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):

{
  "error": "URL must start with http:// or https://"
}

Custom code taken (400 Bad Request):

{
  "error": "Custom code already taken"
}

Invalid custom code (400 Bad Request):

{
  "error": "Custom code must be 1-32 characters long and contain only letters, numbers, underscores, and hyphens"
}

Unauthorized (401 Unauthorized):

{
  "error": "Unauthorized"
}

Get All Links

Retrieve all shortened URLs for the authenticated user.

GET /api/links

Example:

curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/links

Response (200 OK):

[
  {
    "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.

GET /{short_code}?source={source}

Example:

curl -i http://localhost:8080/example?source=email

Response (307 Temporary Redirect):

HTTP/1.1 307 Temporary Redirect
Location: https://example.com

Error Response (404 Not Found):

{
  "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

-- 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);