package openlibrary import ( "encoding/json" "fmt" "strings" ) type OpenLibraryBookResult struct { Title string `json:"title"` Description string `json:"description"` AuthorID string `json:"author_id"` } type openLibraryParsedBook struct { Title string `json:"title"` Description string `json:"description"` AuthorInfo []openLibraryBookAuthorResult `json:"authors"` } type openLibraryBookAuthorResult struct { AuthorOLID string Type string Key string } type keyContainer struct { Key string `json:"key"` } func (r *openLibraryBookAuthorResult) UnmarshalJSON(data []byte) error { var parentAuthor struct { AuthorKey keyContainer `json:"author"` TypeKey keyContainer `json:"type"` Key string `json:"key"` } if err := json.Unmarshal(data, &parentAuthor); err != nil { return err } r.AuthorOLID = parseUrlPathToField(parentAuthor.AuthorKey.Key) r.Type = parseUrlPathToField(parentAuthor.TypeKey.Key) r.Key = parseUrlPathToField(parentAuthor.Key) return nil } // some fields follow this format "/authors/OL274606A" // this method extracts the last part "OL274606A" func parseUrlPathToField(urlpath string) string { splittedPath := strings.Split(urlpath, "/") if len(splittedPath) > 2 { return splittedPath[2] } else { return urlpath } } func CallOpenLibraryBook(openLibraryId string) (OpenLibraryBookResult, error) { var response OpenLibraryBookResult u, err := computeOpenLibraryUrl("works", fmt.Sprintf("%s.json", openLibraryId)) if err != nil { return response, err } var queryResult openLibraryParsedBook err = fetchAndParseResult(u, &queryResult) if err != nil { return response, err } author := computeAuthorFromParsedBook(&queryResult) response = OpenLibraryBookResult{ Title: queryResult.Title, Description: queryResult.Description, AuthorID: author, } return response, err } func computeAuthorFromParsedBook(parsedBook *openLibraryParsedBook) string { authors := parsedBook.AuthorInfo for _, author := range authors { if author.Key != "" { return author.Key } if author.Type == "author_role" { return author.AuthorOLID } } if len(authors) > 0 { return authors[0].AuthorOLID } return "" }