Files
thrillwiki_django_no_react/shared/docs/api/README.md
pacnpal e62646bcf9 feat: major API restructure and Vue.js frontend integration
- Centralize API endpoints in dedicated api app with v1 versioning
- Remove individual API modules from parks and rides apps
- Add event tracking system with analytics functionality
- Integrate Vue.js frontend with Tailwind CSS v4 and TypeScript
- Add comprehensive database migrations for event tracking
- Implement user authentication and social provider setup
- Add API schema documentation and serializers
- Configure development environment with shared scripts
- Update project structure for monorepo with frontend/backend separation
2025-08-24 16:42:20 -04:00

13 KiB

ThrillWiki API Documentation

Complete API reference for the ThrillWiki Django REST API backend.

Overview

The ThrillWiki API provides comprehensive access to theme park and roller coaster data through a RESTful interface designed specifically for the Vue.js frontend. The API uses Django REST Framework with custom frontend-compatible serializers that convert Django's snake_case to JavaScript's camelCase convention.

Base URL: http://localhost:8000/api/

Authentication

The API currently supports anonymous access for read operations. Authentication will be added in future versions for write operations and user-specific features.

API Endpoints

Parks

List Parks

GET /api/parks/

Response Format:

{
  "count": 150,
  "next": "http://localhost:8000/api/parks/?page=2",
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "Cedar Point",
      "slug": "cedar-point",
      "location": "Sandusky, Ohio",
      "operator": "Cedar Fair",
      "openingYear": 1870,
      "status": "open",
      "description": "America's Roller Coast",
      "website": "https://www.cedarpoint.com",
      "imageUrl": "/placeholder-park.jpg"
    }
  ]
}

Query Parameters:

  • page - Page number for pagination
  • search - Search parks by name or location
  • status - Filter by park status (open, closed, seasonal)
  • operator - Filter by operator name

Get Park Details

GET /api/parks/{id}/

Response Format:

{
  "id": 1,
  "name": "Cedar Point",
  "slug": "cedar-point",
  "location": "Sandusky, Ohio",
  "operator": "Cedar Fair",
  "openingYear": 1870,
  "status": "open",
  "description": "America's Roller Coast",
  "website": "https://www.cedarpoint.com",
  "imageUrl": "/placeholder-park.jpg",
  "averageRating": 4.5,
  "rideCount": 72,
  "coasterCount": 17,
  "sizeAcres": 364,
  "operatingSeason": "May-October"
}

Rides

List Rides

GET /api/rides/

Response Format:

{
  "count": 500,
  "next": "http://localhost:8000/api/rides/?page=2",
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "Millennium Force",
      "slug": "millennium-force",
      "parkId": 1,
      "parkName": "Cedar Point",
      "parkSlug": "cedar-point",
      "category": "roller_coaster",
      "manufacturer": "Intamin",
      "designer": "Werner Stengel",
      "openingYear": 2000,
      "height": 310,
      "speed": 93,
      "length": 6595,
      "inversions": 0,
      "status": "operating",
      "description": "World's tallest complete-circuit roller coaster",
      "imageUrl": "/placeholder-ride.jpg",
      "thrillLevel": "extreme"
    }
  ]
}

Query Parameters:

  • page - Page number for pagination
  • search - Search rides by name
  • park - Filter by park ID
  • category - Filter by ride category (roller_coaster, dark_ride, flat_ride, water_ride, transport, other)
  • status - Filter by ride status (operating, closed, sbno, under_construction)
  • manufacturer - Filter by manufacturer name
  • thrill_level - Filter by thrill level (family, moderate, intense, extreme)

Get Ride Details

GET /api/rides/{id}/

Response Format:

{
  "id": 1,
  "name": "Millennium Force",
  "slug": "millennium-force",
  "parkId": 1,
  "parkName": "Cedar Point",
  "parkSlug": "cedar-point",
  "category": "roller_coaster",
  "manufacturer": "Intamin",
  "designer": "Werner Stengel",
  "openingYear": 2000,
  "height": 310,
  "speed": 93,
  "length": 6595,
  "inversions": 0,
  "status": "operating",
  "description": "World's tallest complete-circuit roller coaster",
  "imageUrl": "/placeholder-ride.jpg",
  "thrillLevel": "extreme",
  "minHeightIn": 48,
  "maxHeightIn": 78,
  "capacityPerHour": 1300,
  "rideDurationSeconds": 120,
  "averageRating": 4.8,
  "closingDate": null,
  "statusSince": "2000-05-13",
  "coasterStats": {
    "trackMaterial": "steel",
    "coasterType": "hypercoaster",
    "launchType": "chain_lift",
    "maxDropHeightFt": 300,
    "rideTimeSeconds": 120,
    "trainsCount": 2,
    "carsPerTrain": 9,
    "seatsPerCar": 4,
    "trainStyle": "open_air",
    "trackType": "complete_circuit"
  }
}

Get Rides by Park

GET /api/parks/{park_id}/rides/

Returns all rides for a specific park using the same format as the main rides endpoint.

Data Models

Park Data Structure

Field Type Description
id integer Unique park identifier
name string Park name
slug string URL-friendly park identifier
location string Formatted location (e.g., "Sandusky, Ohio")
operator string Park operating company
openingYear integer Year park opened
status string Park status: open, closed, seasonal
description string Park description
website string Official website URL
imageUrl string Primary park image URL
averageRating float Average user rating (detail view only)
rideCount integer Total number of rides (detail view only)
coasterCount integer Number of roller coasters (detail view only)
sizeAcres float Park size in acres (detail view only)
operatingSeason string Operating season description (detail view only)

Ride Data Structure

Field Type Description
id integer Unique ride identifier
name string Ride name
slug string URL-friendly ride identifier
parkId integer Parent park ID
parkName string Parent park name
parkSlug string Parent park slug
category string Ride category
manufacturer string Ride manufacturer
designer string Ride designer
openingYear integer Year ride opened
height float Height in feet (coasters only)
speed float Speed in mph (coasters only)
length float Length in feet (coasters only)
inversions integer Number of inversions (coasters only)
status string Ride status
description string Ride description
imageUrl string Primary ride image URL
thrillLevel string Calculated thrill level
minHeightIn integer Minimum height requirement (detail view only)
maxHeightIn integer Maximum height requirement (detail view only)
capacityPerHour integer Hourly capacity (detail view only)
rideDurationSeconds integer Ride duration in seconds (detail view only)
averageRating float Average user rating (detail view only)
closingDate date Date ride closed (detail view only)
statusSince date Date status changed (detail view only)
coasterStats object Detailed coaster statistics (detail view only)

Coaster Statistics Structure

Field Type Description
trackMaterial string Track material (steel, wood)
coasterType string Coaster type (hypercoaster, inverted, etc.)
launchType string Launch mechanism
maxDropHeightFt float Maximum drop height in feet
rideTimeSeconds integer Total ride time in seconds
trainsCount integer Number of trains
carsPerTrain integer Cars per train
seatsPerCar integer Seats per car
trainStyle string Train style (open_air, enclosed)
trackType string Track configuration

Field Mappings

Django to Frontend Field Conversion

The API automatically converts Django's snake_case field names to JavaScript's camelCase convention:

Django Model Frontend API
opening_date openingYear
min_height_in minHeightIn
max_height_in maxHeightIn
capacity_per_hour capacityPerHour
ride_duration_seconds rideDurationSeconds
coaster_stats coasterStats
size_acres sizeAcres
ride_count rideCount
coaster_count coasterCount
average_rating averageRating

Status Mappings

Park Status

Django Frontend
OPERATING open
CLOSED_TEMP seasonal
CLOSED_PERM closed
UNDER_CONSTRUCTION closed
DEMOLISHED closed
RELOCATED closed

Ride Status

Django Frontend
OPERATING operating
CLOSED_TEMP closed
SBNO sbno
CLOSING closed
CLOSED_PERM closed
UNDER_CONSTRUCTION under_construction
DEMOLISHED closed
RELOCATED closed

Category Mappings

Ride Categories

Django Frontend
RC roller_coaster
DR dark_ride
FR flat_ride
WR water_ride
TR transport
OT other

Error Handling

The API returns standard HTTP status codes with detailed error information:

Error Response Format

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Park with id 999 not found",
    "details": {}
  }
}

Common HTTP Status Codes

  • 200 OK - Successful request
  • 201 Created - Resource created successfully
  • 400 Bad Request - Invalid request data
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Resource not found
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Pagination

List endpoints support pagination with the following format:

{
  "count": 150,
  "next": "http://localhost:8000/api/parks/?page=2",
  "previous": null,
  "results": [...]
}

Query Parameters:

  • page - Page number (default: 1)
  • page_size - Items per page (default: 20, max: 100)

Rate Limiting

The API implements rate limiting to prevent abuse:

  • Anonymous users: 100 requests per hour
  • Authenticated users: 1000 requests per hour

Rate limit headers are included in responses:

  • X-RateLimit-Limit - Request limit per hour
  • X-RateLimit-Remaining - Remaining requests
  • X-RateLimit-Reset - Time until reset (Unix timestamp)

CORS Configuration

The API is configured to work with the Vue.js frontend:

  • Allowed origins: http://localhost:5174 (development)
  • Allowed methods: GET, POST, PUT, DELETE, OPTIONS
  • Allowed headers: Content-Type, Authorization, X-Requested-With

Frontend Integration

Vue.js Service Layer

The frontend uses dedicated service functions for API communication:

// services/parkService.ts
export const parkService = {
  async getParks(params?: ParkQueryParams): Promise<PaginatedResponse<Park>> {
    const response = await apiClient.get('/parks/', { params });
    return response.data;
  },

  async getPark(id: number): Promise<ParkDetail> {
    const response = await apiClient.get(`/parks/${id}/`);
    return response.data;
  }
};

Pinia Store Integration

API responses are managed through Pinia stores:

// stores/parks.ts
export const useParksStore = defineStore('parks', () => {
  const parks = ref<Park[]>([]);
  const loading = ref(false);

  const fetchParks = async () => {
    loading.value = true;
    try {
      const response = await parkService.getParks();
      parks.value = response.results;
    } finally {
      loading.value = false;
    }
  };

  return { parks, loading, fetchParks };
});

Development & Testing

API Testing with curl

# Get list of parks
curl "http://localhost:8000/api/parks/"

# Get specific park
curl "http://localhost:8000/api/parks/1/"

# Search parks
curl "http://localhost:8000/api/parks/?search=cedar"

# Filter by status
curl "http://localhost:8000/api/parks/?status=open"

Django REST Framework Browsable API

When DEBUG=True, the API provides a browsable interface at each endpoint URL. This interface allows:

  • Interactive API browsing
  • Form-based testing
  • Authentication testing
  • Request/response inspection

Future Enhancements

Planned Features

  • Authentication & Authorization - JWT-based user authentication
  • User Preferences - Personalized park/ride recommendations
  • Image Upload - User-contributed photos
  • Review System - User ratings and reviews
  • Social Features - Following parks/rides, activity feeds
  • Advanced Search - Full-text search with filters
  • Real-time Updates - WebSocket support for live data

API Versioning

Future API versions will be supported via URL versioning:

  • /api/v1/parks/ - Version 1 (current)
  • /api/v2/parks/ - Version 2 (future)

Support

For API-related questions or issues:

Changelog

Version 1.0.0

  • Initial API release
  • Parks and rides endpoints
  • Frontend-compatible serialization
  • Pagination and filtering support
  • CORS configuration for Vue.js integration