FOV Backend - API Testing & Examples
Quick reference for testing the FOV Backend API endpoints.
API Base URL
Development: http://localhost:4000
Production: https://api.yourdomain.com
Health Check
Check Server Status
Request:
curl http://localhost:4000/
Response (200 OK):
{
"ok": true,
"message": "FOV backend running"
}
Users Endpoints
Get User by ID (GET)
Request:
curl http://localhost:4000/api/users/1
Response (200 OK):
{
"data": {
"id": 1,
"username": "john_doe",
"display_name": "John Doe",
"created_at": "2026-01-15T10:30:00Z"
}
}
Response (404 Not Found):
{
"error": "User not found"
}
Create User (POST)
Request:
curl -X POST http://localhost:4000/api/users \
-H "Content-Type: application/json" \
-d '{
"username": "jane_smith",
"display_name": "Jane Smith"
}'
Response (201 Created):
{
"id": 42
}
Error (400 Bad Request):
# Missing username
curl -X POST http://localhost:4000/api/users \
-H "Content-Type: application/json" \
-d '{"display_name": "No Username"}'
Response:
{
"error": "username required"
}
Categories Endpoints
List All Categories (GET)
Request:
curl http://localhost:4000/api/categories
Response (200 OK):
[
{
"id": 1,
"name": "Gaming",
"viewers": 1250,
"image_url": "http://localhost:4000/images/gaming.jpg"
},
{
"id": 2,
"name": "Music",
"viewers": 890,
"image_url": "http://localhost:4000/images/music.jpg"
}
]
Get Category by ID (GET)
Request:
curl http://localhost:4000/api/categories/1
Response (200 OK):
{
"id": 1,
"name": "Gaming",
"viewers": 1250,
"image_url": "http://localhost:4000/images/gaming.jpg"
}
Streams Endpoints
List All Streams (GET)
Request:
curl http://localhost:4000/api/streams
Response (200 OK):
{
"data": [
[
{
"id": 1,
"streamer": "john_doe",
"title": "Epic Gaming Session",
"category_id": 1,
"viewers": 245,
"thumbnail_url": "http://localhost:4000/images/stream1.jpg",
"avatar_url": "http://localhost:4000/images/avatar1.jpg",
"is_live": 1
},
{
"id": 2,
"streamer": "jane_smith",
"title": "Music Production Stream",
"category_id": 2,
"viewers": 128,
"thumbnail_url": "http://localhost:4000/images/stream2.jpg",
"avatar_url": "http://localhost:4000/images/avatar2.jpg",
"is_live": 1
}
]
Get Stream by ID (GET)
Request:
curl http://localhost:4000/api/streams/1
Response (200 OK):
{
"id": 1,
"streamer": "john_doe",
"title": "Epic Gaming Session",
"category_id": 1,
"viewers": 245,
"thumbnail_url": "http://localhost:4000/images/stream1.jpg",
"avatar_url": "http://localhost:4000/images/avatar1.jpg",
"is_live": 1
}
Get Available Streams with HLS Tracks (GET)
Request:
curl http://localhost:4000/api/streams/available
Response (200 OK):
[
{
"streamId": "1",
"trackCount": 2,
"tracks": [
{
"trackId": "v:0",
"videoUrl": "http://localhost:4000/hls/1/v:0/playlist.m3u8"
},
{
"trackId": "v:1",
"videoUrl": "http://localhost:4000/hls/1/v:1/playlist.m3u8"
}
],
"title": "Epic Gaming Session",
"category": "Gaming",
"viewers": 245,
"avatarUrl": "http://localhost:4000/images/avatar1.jpg",
"thumbnailUrl": "http://localhost:4000/images/stream1.jpg"
}
]
Get Stream HLS URL (GET)
Request:
curl http://localhost:4000/api/streams/1/hls
Response (200 OK):
{
"hls": "http://localhost:4000/hls/live/1/playlist.m3u8"
}
Get HLS Playlist
Request:
curl http://localhost:4000/hls/1/v:0/playlist.m3u8
Response (200 OK):
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXTINF:2.0,
seg00000.ts
#EXTINF:2.0,
seg
---
## Testing with cURL
### Using cURL Variables
**Save base URL:**
```bash
BASE_URL="http://localhost:4000"
# Create user
curl -X POST $BASE_URL/api/users \
-H "Content-Type: application/json" \
-d '{"username":"testuser"}'
# Get user
curl $BASE_URL/api/users/1
Debugging with Verbose Output
Show request and response headers:
curl -v http://localhost:4000/api/users/1
Show only headers:
curl -i http://localhost:4000/api/users/1
Testing with JavaScript/Node.js
Using Fetch API
// Create user
const response = await fetch('http://localhost:4000/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'testuser',
display_name: 'Test User'
})
});
const data = await response.json();
console.log('Created user ID:', data.id);
// Get user
const userResponse = await fetch('http://localhost:4000/api/users/1');
const user = await userResponse.json();
console.log('User:', user.data);
Using axios
const axios = require('axios');
const api = axios.create({
baseURL: 'http://localhost:4000'
});
// Create user
const createResponse = await api.post('/api/users', {
username: 'testuser',
display_name: 'Test User'
});
console.log('User ID:', createResponse.data.id);
// Get user
const getUserResponse = await api.get('/api/users/1');
console.log('User:', getUserResponse.data);
Automated Testing
Run Test Suite
# Run all tests
npm test
# Run specific test file
npm test -- users.test.js
# Watch mode
npm run test:watch
# With coverage
npm test -- --coverage
Example Test Run
$ npm test
PASS src/__tests__/users.test.js
Users Routes
GET /:id
✓ should return user by id (45ms)
✓ should return 404 when user not found (12ms)
✓ should handle database errors (8ms)
POST /
✓ should create a new user (38ms)
✓ should return 400 when username is missing (5ms)
✓ should handle database errors on create (6ms)
Test Suites: 1 passed, 1 total
Tests: 6 passed, 6 total
Time: 2.345s
Coverage summary:
Statements : 62% ( 123/198 )
Branches : 48% ( 72/150 )
Functions : 70% ( 35/50 )
Lines : 65% ( 128/197 )
Error Testing
Test Error Scenarios
# Missing required field
curl -X POST http://localhost:4000/api/users \
-H "Content-Type: application/json" \
-d '{}'
# Response (400)
# {"error":"username required"}
# Non-existent resource
curl http://localhost:4000/api/users/99999
# Response (404)
# {"error":"User not found"}
# Invalid method
curl -X DELETE http://localhost:4000/api/users/1
# Response (405)
# Method not allowed
# Server error simulation
# (Manually stop database)
curl http://localhost:4000/api/users/1
# Response (500)
# {"error":"Unable to connect to DB..."}
Performance Testing
Response Time Measurement
# Measure response time
time curl -s http://localhost:4000/api/users/1 > /dev/null
# Example output:
# real 0m0.125s
# user 0m0.032s
# sys 0m0.024s
# Should be < 500ms for good performance
Database Query Performance
Enable MySQL slow query log:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5; -- 500ms threshold
-- Tail the log
TAIL /var/log/mysql/slow.log
Debugging
Enable Verbose Logging
In development:
NODE_ENV=development npm run dev
In code:
console.log('Debug info:', variable);
View Server Logs
# Docker
docker logs -f fov-backend
# Local process
tail -f ~/.pm2/logs/backend-out.log
# Check specific endpoint
curl -v http://localhost:4000/api/users/1
Testing Checklist
Before considering API ready:
- Health Check:
GET /returns 200 - Create User:
POST /api/usersreturns 201 with ID - Get User:
GET /api/users/:idreturns 200 - Not Found:
GET /api/users/999returns 404 - Validation: Missing fields return 400
- Errors: Database errors return 500 (not stacktrace)
- Categories: CRUD operations work
- Streams: All endpoints respond
- Performance: Responses < 500ms
- Tests Pass:
npm testshows all green - Linting Passes:
npm run lintshows no errors
Last Updated: April 2026