High-Performance Video Streaming API in Go for Global Markets

go dev.to

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"`
}
Enter fullscreen mode Exit fullscreen mode

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})
}
Enter fullscreen mode Exit fullscreen mode

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())
}
Enter fullscreen mode Exit fullscreen mode

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.

Source: dev.to

arrow_back Back to Tutorials