aboutsummaryrefslogtreecommitdiff
path: root/api.go
diff options
context:
space:
mode:
Diffstat (limited to 'api.go')
-rw-r--r--api.go88
1 files changed, 44 insertions, 44 deletions
diff --git a/api.go b/api.go
index fa91ea6..21a2b5f 100644
--- a/api.go
+++ b/api.go
@@ -1,58 +1,58 @@
package main
import (
- "fmt"
- "io"
"log"
+ "encoding/json"
"net/http"
+ "time"
)
-const youtubeAPI = "https://www.googleapis.com/youtube/v3/"
-
-/* function to make an api request */
-func apiRequest(w http.ResponseWriter, r *http.Request, endpoint string, videoIdParam string, part string) {
- videoID := r.URL.Query().Get("id")
- if videoID == "" {
- msg := "Missing ?id=VIDEO_ID parameter"
- http.Error(w, msg, http.StatusBadRequest)
- return
- }
+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"`
+}
- if apiKey == "" {
- msg := "API_KEY environment variable not set"
- http.Error(w, msg, http.StatusInternalServerError)
- log.Println(msg)
- return
- }
+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"`
+}
- url := fmt.Sprintf("%s?part=%s&%s=%s&key=%s", youtubeAPI + endpoint, part, videoIdParam, videoID, apiKey)
- resp, err := http.Get(url)
- if err != nil {
- msg := "Failed to fetch video info: " + err.Error()
- http.Error(w, msg, http.StatusInternalServerError)
- log.Println(msg)
- return
- }
- defer resp.Body.Close()
+type APISource interface {
+ getDetails(id string) (VideoDetails, error)
+ getComments(id string) ([]Comment, error)
+}
- if resp.StatusCode != http.StatusOK {
- msg := "YouTube API error: " + resp.Status
- http.Error(w, msg, http.StatusBadGateway)
- log.Println(msg)
- return
+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)
}
-
- w.Header().Set("Content-Type", "application/json")
- io.Copy(w, resp.Body)
}
-/* routes */
-func setupRoutesAPI() {
- http.HandleFunc("/api/details", func(w http.ResponseWriter, r *http.Request) {
- apiRequest(w, r, "videos", "id", "snippet,statistics,topicDetails")
- })
-
- http.HandleFunc("/api/comments", func(w http.ResponseWriter, r *http.Request) {
- apiRequest(w, r, "commentThreads", "videoId", "snippet,replies&maxResults=100")
- })
+func registerRoutesAPI(mux *http.ServeMux, api APISource) {
+ mux.HandleFunc("/api/details", apiDataHandler(api.getDetails))
+ mux.HandleFunc("/api/comments", apiDataHandler(api.getComments))
}