package main import ( "log" "encoding/json" "net/http" "time" ) type VideoDetails struct { Channel string `json:"channel"` DatePublished time.Time `json:"datePublished"` Description string `json:"description"` NumComments int `json:"comments"` NumLikes int `json:"likes"` NumViews int `json:"views"` Tags []string `json:"tags"` } type Comment struct { Author string `json:"a"` Body string `json:"b"` DatePublished time.Time `json:"p"` DateUpdated time.Time `json:"u"` Likes int `json:"l"` Replies []*Comment `json:"r,omitempty"` } type APISource interface { getDetails(id string) (VideoDetails, error) getComments(id string) ([]Comment, error) } func apiDataHandler[T any](f func(id string) (T, error)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { videoID := r.URL.Query().Get("id") if videoID == "" { msg := "Missing ?id=VIDEO_ID parameter" http.Error(w, msg, http.StatusBadRequest) return } data, err := f(videoID) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Println(err.Error()) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) } } func registerRoutesAPI(mux *http.ServeMux, api APISource) { mux.HandleFunc("/api/details", apiDataHandler(api.getDetails)) mux.HandleFunc("/api/comments", apiDataHandler(api.getComments)) }