aboutsummaryrefslogtreecommitdiff
path: root/api.go
blob: 21a2b5faaccdeb753673eeb8680f4f2b292f2f3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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))
}