YouTube Videos API — Dokumentasi
Versi: 1.0 • Terakhir diperbarui: 2025-11-04 04:00:58 (Asia/Jakarta)
Komponen: app/routes/youtube.py (Blueprint Flask)
Ringkasan
API ini mengelola daftar video YouTube (CRUD) dan menyediakan utilitas untuk membangun URL embed serta thumbnail dari YouTube Video ID (11 karakter). API menerima baik YouTube ID langsung maupun berbagai format URL YouTube (watch, embed, shorts, youtu.be) dan akan mengekstrak ID-nya secara otomatis.
Base URL
Blueprint didefinisikan dengan url_prefix="/youtube_videos". Jika aplikasi utama mendaftarkan blueprint di bawah /api, maka base URL efektif adalah:
- Base (disarankan):
/api/youtube_videos - Jika tanpa prefix global:
/youtube_videos
Contoh di bawah ini menggunakan prefix
/api.
Autentikasi
Tidak ada logika autentikasi/otorisasi di dalam file ini. Jika API harus dilindungi (disarankan), tambahkan middleware (mis. JWT) di level app atau blueprint sebelum rilis produksi.
Skema Data
Tabel yang digunakan: youtube_videos
Kolom yang dipakai oleh API:
id(INT, PK, AUTO_INCREMENT)youtube_id(VARCHAR(11)) — WAJIB • valid regex:^[A-Za-z0-9_-]{11}$title(VARCHAR/TEXT kecil) — WAJIBis_active(TINYINT(1) / BOOL) — default 1sort_order(INT) — boleh negatif/positif (batas -10000..10000)created_at(DATETIME) — diisiNOW()saat insertupdated_at(DATETIME) — diisiNOW()saat insert & update
Contoh ringkas DDL (sesuaikan tipe & index sesuai kebutuhan):
CREATE TABLE youtube_videos (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
youtube_id VARCHAR(11) NOT NULL,
title VARCHAR(255) NOT NULL,
is_active TINYINT(1) NOT NULL DEFAULT 1,
sort_order INT NOT NULL DEFAULT 0,
created_at DATETIME NULL DEFAULT NULL,
updated_at DATETIME NULL DEFAULT NULL,
KEY idx_active (is_active),
KEY idx_sort (sort_order)
);
Ekstraksi YouTube ID
Fungsi: extract_youtube_id(raw: str) -> Optional[str]
Menerima salah satu dari:
- ID langsung:
dQw4w9WgXcQ - URL:
https://www.youtube.com/watch?v=dQw4w9WgXcQhttps://youtu.be/dQw4w9WgXcQhttps://www.youtube.com/embed/dQw4w9WgXcQhttps://www.youtube.com/shorts/dQw4w9WgXcQ
Jika valid → kembalikan 11-char ID. Jika tidak valid → None (akan diperlakukan sebagai error 400 di endpoint yang relevan).
Utilitas Terkait
build_embed(yid)→https://www.youtube.com/embed/<yid>build_thumb(yid)→https://img.youtube.com/vi/<yid>/hqdefault.jpg
Endpoints
1) List Videos
GET /api/youtube_videos?limit=10&active=1&q=profile
Query Params
limit— integer 1..50, default 10active—"0"atau"1", default "1" (hanya aktif). Jika ingin semua, hilangkan param tersebut.q— substring pencarian pada kolomtitle
Sort
ORDER BY sort_order ASC, id DESC
Response 200
{
"ok": true,
"data": [
{
"id": 123,
"title": "Company Profile 2025",
"youtube_id": "dQw4w9WgXcQ",
"is_active": 1,
"sort_order": 10,
"created_at": "2025-11-01 09:30:00",
"updated_at": "2025-11-03 14:22:10",
"embed_url": "https://www.youtube.com/embed/dQw4w9WgXcQ",
"thumbnail_url": "https://img.youtube.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
}
]
}
Response 500
{ "ok": false, "error": "penjelasan kesalahan" }
2) Get by ID
GET /api/youtube_videos/{id}
Path Param
id— integer (PK)
Response 200
{
"ok": true,
"data": {
"id": 123,
"title": "Company Profile 2025",
"youtube_id": "dQw4w9WgXcQ",
"is_active": 1,
"sort_order": 10,
"created_at": "2025-11-01 09:30:00",
"updated_at": "2025-11-03 14:22:10",
"embed_url": "https://www.youtube.com/embed/dQw4w9WgXcQ",
"thumbnail_url": "https://img.youtube.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
}
}
Response 404
{ "ok": false, "error": "Video tidak ditemukan" }
Response 500
{ "ok": false, "error": "penjelasan kesalahan" }
3) Create Video
POST /api/youtube_videos
Body (JSON)
title(string, wajib)- Salah satu dari:
youtube_id(string, 11 char valid), atauurl(string, format URL YouTube)
is_active(0/1, opsional, default 1)sort_order(int, opsional, default 0; rentang -10000..10000)
Contoh Request
{
"title": "Profile SJS 2025",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"is_active": 1,
"sort_order": 5
}
Response 201
{
"ok": true,
"id": 456,
"youtube_id": "dQw4w9WgXcQ",
"embed_url": "https://www.youtube.com/embed/dQw4w9WgXcQ",
"thumbnail_url": "https://img.youtube.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
"message": "Video ditambahkan"
}
Response 400 (contoh)
{ "ok": false, "error": "title & youtube_id/url wajib dan valid" }
Response 500
{ "ok": false, "error": "penjelasan kesalahan" }
4) Update Video
PATCH /api/youtube_videos/{id}
Path Param
id— integer (PK)
Body (JSON) — isi salah satu/lebih field berikut:
title(string) — tidak boleh kosongis_active(0/1)sort_order(int; -10000..10000)youtube_id(11 char valid) atauurl(format URL YouTube)
Contoh Request
{
"title": "Profil SJS 2025 (Update)",
"is_active": 1,
"sort_order": 8
}
Response 200
{ "ok": true, "message": "Video diperbarui" }
Response 400 (contoh)
{ "ok": false, "error": "Tidak ada field yang diubah" }
{ "ok": false, "error": "title tidak boleh kosong" }
{ "ok": false, "error": "youtube_id/url tidak valid" }
Response 404
{ "ok": false, "error": "Video tidak ditemukan" }
Response 500
{ "ok": false, "error": "penjelasan kesalahan" }
5) Delete Video
DELETE /api/youtube_videos/{id}
Path Param
id— integer (PK)
Response 200
{ "ok": true, "message": "Video dihapus" }
Response 404
{ "ok": false, "error": "Video tidak ditemukan" }
Response 500
{ "ok": false, "error": "penjelasan kesalahan" }
Contoh curl
List (aktif saja, limit 5)
curl -s "https://https://api-sjs.bizpro.my.id/api/youtube_videos?active=1&limit=5"
Cari judul mengandung 'profile'
curl -s "https://https://api-sjs.bizpro.my.id/api/youtube_videos?q=profile"
Get by ID
curl -s "https://https://api-sjs.bizpro.my.id/api/youtube_videos/123"
Create (pakai URL)
curl -s -X POST "https://https://api-sjs.bizpro.my.id/api/youtube_videos" -H "Content-Type: application/json" -d '{"title":"Profile SJS 2025","url":"https://youtu.be/dQw4w9WgXcQ","is_active":1,"sort_order":5}'
Update (title + sort_order)
curl -s -X PATCH "https://https://api-sjs.bizpro.my.id/api/youtube_videos/123" -H "Content-Type: application/json" -d '{"title":"Profil 2025 (Update)","sort_order":8}'
Delete
curl -s -X DELETE "https://https://api-sjs.bizpro.my.id/api/youtube_videos/123"
Validasi & Edge Cases
titlewajib padaPOST; padaPATCHjika dikirim, tidak boleh kosong.youtube_id/urlwajib padaPOST; padaPATCHjika salah satu dikirim, harus valid.limitdibatasi1..50(default 10).sort_orderdibatasi[-10000..10000].- Timestamp pada respons diformat
"YYYY-MM-DD HH:MM:SS"jika tersedia di DB.
Endpoint
GET /(list) tidak menyediakan pagination offset/next-token; gunakanlimitdan sorting untuk kebutuhan tampilan yang sederhana.
Struktur Respons
Berikut pola respons konsisten di seluruh endpoint:
- Sukses:
{ "ok": true, ... } - Gagal:
{ "ok": false, "error": "pesan" }
Catatan Produksi
- Tambahkan auth (JWT/OAuth/session) sebelum dipublikasi.
- Sanitasi input tambahan untuk
titlebila diperlukan (mis. panjang maksimal). - Tambahkan index untuk
title/is_activejika query pencarian sering digunakan. - Pertimbangkan rate limiting & logging untuk operasional.
- Untuk reliabilitas MySQL, gunakan pool koneksi (di file ini dibuat koneksi per-request secara sederhana).
Changelog
- v1.0 — Dokumentasi awal berdasarkan implementasi
youtube.py.