package openlibrary import ( "encoding/json" "io" "net/http" "net/url" "strconv" "strings" ) type OpenLibraryQueryResult struct { Books []OpenLibraryBook `json:"docs"` NumFound int `json:"numFound"` } type OpenLibraryBook struct { Title string `json:"title"` Authors []string `json:"author_name"` OpenLibraryId string `json:"cover_edition_key"` } func CallOpenLibrary(searchterm string, limit int, offset int) (OpenLibraryQueryResult, error) { var queryResult OpenLibraryQueryResult baseUrl := "https://openlibrary.org" booksApiUrl := "search.json" u, err := url.Parse(baseUrl) if err != nil { return queryResult, err } u = u.JoinPath(booksApiUrl) if limit != 0 { addQueryParamInt(u, "limit", limit) } if offset != 0 { addQueryParamInt(u, "offset", offset) } addQueryParam(u, "q", searchterm) client := &http.Client{} req, err := http.NewRequest("GET", u.String(), nil) if err != nil { return queryResult, err } req.Header.Add("Accept", "application/json") req.Header.Add("User-Agent", "PersonalLibraryManager/0.1 (artlef@protonmail.com)") resp, err := client.Do(req) if err != nil { return queryResult, err } defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) if err != nil { return queryResult, err } bodyString := string(bodyBytes) decoder := json.NewDecoder(strings.NewReader(bodyString)) err = decoder.Decode(&queryResult) return queryResult, err } func addQueryParamInt(u *url.URL, paramName string, paramValue int) { addQueryParam(u, paramName, strconv.Itoa(paramValue)) } func addQueryParam(u *url.URL, paramName string, paramValue string) { q := u.Query() q.Set(paramName, paramValue) u.RawQuery = q.Encode() }