# 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 ```http GET /api/parks/ ``` **Response Format:** ```json { "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 ```http GET /api/parks/{id}/ ``` **Response Format:** ```json { "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 ```http GET /api/rides/ ``` **Response Format:** ```json { "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 ```http GET /api/rides/{id}/ ``` **Response Format:** ```json { "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 ```http 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 ```json { "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: ```json { "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: ```typescript // services/parkService.ts export const parkService = { async getParks(params?: ParkQueryParams): Promise> { const response = await apiClient.get('/parks/', { params }); return response.data; }, async getPark(id: number): Promise { const response = await apiClient.get(`/parks/${id}/`); return response.data; } }; ``` ### Pinia Store Integration API responses are managed through Pinia stores: ```typescript // stores/parks.ts export const useParksStore = defineStore('parks', () => { const parks = ref([]); 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 ```bash # 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: - Check the [Django REST Framework documentation](https://www.django-rest-framework.org/) - Review the [frontend integration guide](../frontend/README.md) - Create an issue in the project repository ## 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