Integrate OpenAPI/Swagger documentation using drf-spectacular, enhancing API documentation with comprehensive guides and schema generation. Add multiple documentation files covering authentication, error codes, rate limiting, and migration strategies. Update settings and URLs to support new documentation endpoints and schema configurations.

This commit is contained in:
IGNY8 VPS (Salman)
2025-11-16 02:15:37 +00:00
parent 452d065c22
commit 79648db07f
16 changed files with 3501 additions and 6 deletions

365
docs/MIGRATION-GUIDE.md Normal file
View File

@@ -0,0 +1,365 @@
# API Migration Guide
**Version**: 1.0.0
**Last Updated**: 2025-11-16
Guide for migrating existing API consumers to IGNY8 API Standard v1.0.
---
## Overview
The IGNY8 API v1.0 introduces a unified response format that standardizes all API responses. This guide helps you migrate existing code to work with the new format.
---
## What Changed
### Before (Legacy Format)
**Success Response**:
```json
{
"id": 1,
"name": "Keyword",
"status": "active"
}
```
**Error Response**:
```json
{
"detail": "Not found."
}
```
### After (Unified Format v1.0)
**Success Response**:
```json
{
"success": true,
"data": {
"id": 1,
"name": "Keyword",
"status": "active"
},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
**Error Response**:
```json
{
"success": false,
"error": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
---
## Migration Steps
### Step 1: Update Response Parsing
#### Before
```python
response = requests.get(url, headers=headers)
data = response.json()
# Direct access
keyword_id = data['id']
keyword_name = data['name']
```
#### After
```python
response = requests.get(url, headers=headers)
data = response.json()
# Check success first
if data['success']:
# Extract data from unified format
keyword_data = data['data'] # or data['results'] for lists
keyword_id = keyword_data['id']
keyword_name = keyword_data['name']
else:
# Handle error
error_message = data['error']
raise Exception(error_message)
```
### Step 2: Update Error Handling
#### Before
```python
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
except requests.HTTPError as e:
if e.response.status_code == 404:
print("Not found")
elif e.response.status_code == 400:
print("Bad request")
```
#### After
```python
response = requests.get(url, headers=headers)
data = response.json()
if not data['success']:
# Unified error format
error_message = data['error']
field_errors = data.get('errors', {})
if response.status_code == 404:
print(f"Not found: {error_message}")
elif response.status_code == 400:
print(f"Validation error: {error_message}")
for field, errors in field_errors.items():
print(f" {field}: {', '.join(errors)}")
```
### Step 3: Update Pagination Handling
#### Before
```python
response = requests.get(url, headers=headers)
data = response.json()
results = data['results']
next_page = data['next']
count = data['count']
```
#### After
```python
response = requests.get(url, headers=headers)
data = response.json()
if data['success']:
# Paginated response format
results = data['results'] # Same field name
next_page = data['next'] # Same field name
count = data['count'] # Same field name
else:
# Handle error
raise Exception(data['error'])
```
### Step 4: Update Frontend Code
#### Before (JavaScript)
```javascript
const response = await fetch(url, { headers });
const data = await response.json();
// Direct access
const keywordId = data.id;
const keywordName = data.name;
```
#### After (JavaScript)
```javascript
const response = await fetch(url, { headers });
const data = await response.json();
// Check success first
if (data.success) {
// Extract data from unified format
const keywordData = data.data || data.results;
const keywordId = keywordData.id;
const keywordName = keywordData.name;
} else {
// Handle error
console.error('Error:', data.error);
if (data.errors) {
// Handle field-specific errors
Object.entries(data.errors).forEach(([field, errors]) => {
console.error(`${field}: ${errors.join(', ')}`);
});
}
}
```
---
## Helper Functions
### Python Helper
```python
def parse_api_response(response):
"""Parse unified API response format"""
data = response.json()
if data.get('success'):
# Return data or results
return data.get('data') or data.get('results')
else:
# Raise exception with error details
error_msg = data.get('error', 'Unknown error')
errors = data.get('errors', {})
if errors:
error_msg += f": {errors}"
raise Exception(error_msg)
# Usage
response = requests.get(url, headers=headers)
keyword_data = parse_api_response(response)
```
### JavaScript Helper
```javascript
function parseApiResponse(data) {
if (data.success) {
return data.data || data.results;
} else {
const error = new Error(data.error);
error.errors = data.errors || {};
throw error;
}
}
// Usage
const response = await fetch(url, { headers });
const data = await response.json();
try {
const keywordData = parseApiResponse(data);
} catch (error) {
console.error('API Error:', error.message);
if (error.errors) {
// Handle field-specific errors
}
}
```
---
## Breaking Changes
### 1. Response Structure
**Breaking**: All responses now include `success` field and wrap data in `data` or `results`.
**Migration**: Update all response parsing code to check `success` and extract `data`/`results`.
### 2. Error Format
**Breaking**: Error responses now use unified format with `error` and `errors` fields.
**Migration**: Update error handling to use new format.
### 3. Request ID
**New**: All responses include `request_id` for debugging.
**Migration**: Optional - can be used for support requests.
---
## Non-Breaking Changes
### 1. Pagination
**Status**: Compatible - same field names (`count`, `next`, `previous`, `results`)
**Migration**: No changes needed, but wrap in success check.
### 2. Authentication
**Status**: Compatible - same JWT Bearer token format
**Migration**: No changes needed.
### 3. Endpoint URLs
**Status**: Compatible - same endpoint paths
**Migration**: No changes needed.
---
## Testing Migration
### 1. Update Test Code
```python
# Before
def test_get_keyword():
response = client.get('/api/v1/planner/keywords/1/')
assert response.status_code == 200
assert response.json()['id'] == 1
# After
def test_get_keyword():
response = client.get('/api/v1/planner/keywords/1/')
assert response.status_code == 200
data = response.json()
assert data['success'] == True
assert data['data']['id'] == 1
```
### 2. Test Error Handling
```python
def test_not_found():
response = client.get('/api/v1/planner/keywords/99999/')
assert response.status_code == 404
data = response.json()
assert data['success'] == False
assert data['error'] == "Resource not found"
```
---
## Migration Checklist
- [ ] Update response parsing to check `success` field
- [ ] Extract data from `data` or `results` field
- [ ] Update error handling to use unified format
- [ ] Update pagination handling (wrap in success check)
- [ ] Update frontend code (if applicable)
- [ ] Update test code
- [ ] Test all endpoints
- [ ] Update documentation
- [ ] Deploy and monitor
---
## Rollback Plan
If issues arise during migration:
1. **Temporary Compatibility Layer**: Add wrapper to convert unified format back to legacy format
2. **Feature Flag**: Use feature flag to toggle between formats
3. **Gradual Migration**: Migrate endpoints one module at a time
---
## Support
For migration support:
- Review [API Documentation](API-DOCUMENTATION.md)
- Check [Error Codes Reference](ERROR-CODES.md)
- Contact support with `request_id` from failed requests
---
**Last Updated**: 2025-11-16
**API Version**: 1.0.0