High-Performance Video Streaming API in Go for Global Markets
TrendVidStream serves 8 regions across wildly different markets — UAE, Finland, Denmark, Czech Republic, Belgium, Switzerland, US, and UK. Building an API that handles this diversity efficiently is where Go's strengths shine.
Type-Safe Region Handling
package models
import (
"encoding/json"
"fmt"
)
type Region string
const (
AE Region = "AE" // UAE
FI Region = "FI" // Finland
DK Region = "DK" // Denmark
CZ Region = "CZ" // Czech Republic
BE Region = "BE" // Belgium
CH Region = "CH" // Switzerland
US Region = "US"
GB Region = "GB"
)
// RTL returns true for right-to-left script regions.
func (r Region) RTL() bool {
return r == AE
}
// Language returns the primary content language for this region.
func (r Region) Language() string {
switch r {
case AE:
return "ar" // Arabic (plus Hindi, English, Urdu mix)
case FI:
return "fi"
case DK:
return "da"
case CZ:
return "cs"
case BE:
return "fr" // Belgium: French + Dutch mix
case CH:
return "de" // Switzerland: German + French + Italian
default:
return "en"
}
}
var ValidRegions = map[Region]struct{}{
AE: {}, FI: {}, DK: {}, CZ: {}, BE: {}, CH: {}, US: {}, GB: {},
}
func ParseRegion(s string) (Region, error) {
r := Region(s)
if _, ok := ValidRegions[r]; !ok {
return "", fmt.Errorf("invalid region: %q", s)
}
return r, nil
}
type Video struct {
VideoID string `json:"video_id"`
Title string `json:"title"` // UTF-8, may be Arabic
ChannelTitle string `json:"channel_title"`
ThumbnailURL string `json:"thumbnail_url"`
ViewCount int64 `json:"view_count"`
Region Region `json:"region"`
CategoryID int `json:"category_id"`
Language string `json:"language,omitempty"`
IsRTL bool `json:"is_rtl"`
}
HTTP Handler with In-Memory Cache
package handlers
import (
"encoding/json"
"net/http"
"strings"
"sync"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"trendvidstream/internal/models"
)
type Cache struct {
mu sync.RWMutex
entries map[string]cacheEntry
}
type cacheEntry struct {
data []byte
expires time.Time
}
func (c *Cache) Get(key string) ([]byte, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
e, ok := c.entries[key]
if !ok || time.Now().After(e.expires) {
return nil, false
}
return e.data, true
}
func (c *Cache) Set(key string, data []byte, ttl time.Duration) {
c.mu.Lock()
defer c.mu.Unlock()
if c.entries == nil {
c.entries = make(map[string]cacheEntry)
}
c.entries[key] = cacheEntry{data: data, expires: time.Now().Add(ttl)}
}
type TrendingHandler struct {
Pool *pgxpool.Pool
Cache *Cache
}
func (h *TrendingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// /trending/AE, /trending/FI, etc.
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
if len(parts) < 2 {
writeError(w, http.StatusBadRequest, "region required")
return
}
region, err := models.ParseRegion(strings.ToUpper(parts[1]))
if err != nil {
writeError(w, http.StatusNotFound, "invalid region")
return
}
cacheKey := "trending:" + string(region)
if cached, ok := h.Cache.Get(cacheKey); ok {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Cache", "HIT")
if region.RTL() {
w.Header().Set("X-Content-Direction", "rtl")
}
w.Write(cached)
return
}
rows, err := h.Pool.Query(r.Context(), `
SELECT v.video_id, v.title, v.channel_title, v.thumbnail_url,
v.view_count, v.category_id, v.language, vr.region
FROM videos v
JOIN video_regions vr ON vr.video_id = v.id
WHERE vr.region = $1
ORDER BY vr.trending_rank ASC NULLS LAST, v.view_count DESC
LIMIT 50
`, string(region))
if err != nil {
writeError(w, http.StatusInternalServerError, "database error")
return
}
defer rows.Close()
var videos []models.Video
for rows.Next() {
var v models.Video
var lang *string
if err := rows.Scan(&v.VideoID, &v.Title, &v.ChannelTitle,
&v.ThumbnailURL, &v.ViewCount, &v.CategoryID, &lang, &v.Region); err != nil {
continue
}
if lang != nil {
v.Language = *lang
}
v.IsRTL = v.Region.RTL()
videos = append(videos, v)
}
resp := map[string]interface{}{
"region": region, "videos": videos, "total": len(videos),
}
data, _ := json.Marshal(resp)
h.Cache.Set(cacheKey, data, time.Hour)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Cache-Control", "public, max-age=3600")
w.Write(data)
}
func writeError(w http.ResponseWriter, code int, msg string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
json.NewEncoder(w).Encode(map[string]string{"error": msg})
}
Server Setup with Middleware
func main() {
ctx := context.Background()
pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
cache := &handlers.Cache{}
mux := http.NewServeMux()
mux.Handle("/trending/", &handlers.TrendingHandler{Pool: pool, Cache: cache})
mux.Handle("/search", &handlers.SearchHandler{Pool: pool, Cache: cache})
handler := middleware.Logger(middleware.CORS(mux))
srv := &http.Server{
Addr: ":8080", Handler: handler,
ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second,
}
log.Printf("TrendVidStream API serving 8 global regions on :8080")
log.Fatal(srv.ListenAndServe())
}
The Region.RTL() and Region.Language() methods centralize region-specific logic. When a new region is added to TrendVidStream, adding it to the enum automatically surfaces every place in the codebase that needs updating — Go's type system turns incomplete switch statements into compile errors.
This article is part of the Building TrendVidStream series. Check out TrendVidStream to see these techniques in action.