97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
log "github.com/sirupsen/logrus"
|
||
|
"net/http"
|
||
|
)
|
||
|
|
||
|
const API_PREFIX = "https://swapi.dev/api"
|
||
|
|
||
|
// Source: https://swapi.dev/documentation#people
|
||
|
type Person struct {
|
||
|
Name string
|
||
|
// ... other fields unused by this application
|
||
|
}
|
||
|
|
||
|
// Source: https://swapi.dev/documentation#starships
|
||
|
type Starship struct {
|
||
|
Name string
|
||
|
Pilots []string // URLs to retrieve [People]
|
||
|
// ... other fields unused by this application
|
||
|
}
|
||
|
|
||
|
// Structs which may be retrieved in a paginated fasion from swapi.dev
|
||
|
type Pageable interface {
|
||
|
Starship | Person
|
||
|
}
|
||
|
|
||
|
type Gettable interface {
|
||
|
Starship | Person
|
||
|
}
|
||
|
|
||
|
// Represents a single page of [Pageable] structs
|
||
|
type PageOf[T Pageable] struct {
|
||
|
Count uint
|
||
|
Next *string
|
||
|
Previous *string
|
||
|
Results []T
|
||
|
}
|
||
|
|
||
|
// Used for retrieving data from swapi.dev
|
||
|
//
|
||
|
// resp, err := Get("/starships")
|
||
|
//
|
||
|
// If [path] does not start with "/", it assumes you have provided a full URL to
|
||
|
// make following [PageOf]'s [Next] and [Previous] simpler.
|
||
|
//
|
||
|
// resp, err := Get("https://git.lyte.dev/swagger.v1.json")
|
||
|
func Get[T interface{}](path string, data *T) error {
|
||
|
var url string
|
||
|
if path[0] == '/' {
|
||
|
url = API_PREFIX + path
|
||
|
} else {
|
||
|
url = path
|
||
|
}
|
||
|
resp, err := http.Get(url)
|
||
|
if err != nil {
|
||
|
log.Errorf("Error GET'ing %s: %+v", url, err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
err = json.NewDecoder(resp.Body).Decode(data)
|
||
|
if err != nil {
|
||
|
log.Errorf("Failed to decode response JSON: %+v", err)
|
||
|
}
|
||
|
log.Debugf("GET %s: %+v", url, resp)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func AllStarships() (*[]Starship, error) {
|
||
|
results := make([]Starship, 0)
|
||
|
var page PageOf[Starship]
|
||
|
var resp *http.Response
|
||
|
|
||
|
err := Get("/starships", &page)
|
||
|
if err != nil {
|
||
|
return &[]Starship{}, err
|
||
|
}
|
||
|
err = json.NewDecoder(resp.Body).Decode(&page)
|
||
|
log.Debugf("Page: %+v", page)
|
||
|
if err != nil {
|
||
|
log.Errorf("Error decoding response body: %+v", err)
|
||
|
}
|
||
|
results = append(results, page.Results...)
|
||
|
|
||
|
// TODO: loop
|
||
|
for page.Next != nil {
|
||
|
err := Get(*page.Next, &page)
|
||
|
log.Debugf("Page: %+v", page)
|
||
|
if err != nil {
|
||
|
return &[]Starship{}, err
|
||
|
}
|
||
|
json.NewDecoder(resp.Body).Decode(&page)
|
||
|
results = append(results, page.Results...)
|
||
|
}
|
||
|
return &results, nil
|
||
|
}
|