github.com/jakewarren/define@v1.0.1-0.20230216022724-0146b4213218/client.go (about) 1 package dictionary 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "net/http" 7 "net/url" 8 9 "github.com/Rican7/define/source" 10 ) 11 12 const ( 13 // baseURLString is the base URL for all Oxford API interactions 14 baseURLString = "https://od-api.oxforddictionaries.com/api/v2/" 15 16 entriesURLString = baseURLString + "entries/" 17 18 httpRequestAcceptHeaderName = "Accept" 19 httpRequestAppIDHeaderName = "app_id" 20 httpRequestAppKeyHeaderName = "app_key" 21 22 jsonMIMEType = "application/json" 23 ) 24 25 // Client bundles things needed to access the API 26 type Client struct { 27 httpClient *http.Client 28 appID string 29 appKey string 30 } 31 32 // apiURL is the URL instance used for Oxford API calls 33 var apiURL *url.URL 34 35 // New returns a new Oxford API dictionary source 36 func New(httpClient http.Client, appID, appKey string) *Client { 37 return &Client{&httpClient, appID, appKey} 38 } 39 40 // Initialize the package 41 func init() { 42 var err error 43 44 apiURL, err = url.Parse(baseURLString) 45 46 if nil != err { 47 panic(err) 48 } 49 } 50 51 // Define takes a word string and returns a dictionary source.Result 52 func (g *Client) Define(word string) (*Results, error) { 53 // Prepare our URL 54 requestURL, err := url.Parse(entriesURLString + "en/" + word + "?fields=definitions,domains,etymologies,examples,pronunciations,regions,registers&strictMatch=false") 55 56 if nil != err { 57 return nil, err 58 } 59 60 httpRequest, err := http.NewRequest(http.MethodGet, apiURL.ResolveReference(requestURL).String(), nil) 61 62 if nil != err { 63 return nil, err 64 } 65 66 httpRequest.Header.Set(httpRequestAcceptHeaderName, jsonMIMEType) 67 httpRequest.Header.Set(httpRequestAppIDHeaderName, g.appID) 68 httpRequest.Header.Set(httpRequestAppKeyHeaderName, g.appKey) 69 70 httpResponse, err := g.httpClient.Do(httpRequest) 71 72 if nil != err { 73 return nil, err 74 } 75 76 defer httpResponse.Body.Close() 77 78 if http.StatusNotFound == httpResponse.StatusCode { 79 return nil, &source.EmptyResultError{Word: word} 80 } 81 82 if http.StatusForbidden == httpResponse.StatusCode { 83 return nil, &source.AuthenticationError{} 84 } 85 86 body, err := ioutil.ReadAll(httpResponse.Body) 87 88 if nil != err { 89 return nil, err 90 } 91 92 var result Results 93 94 if err = json.Unmarshal(body, &result); nil != err { 95 return nil, err 96 } 97 98 if len(result.Results) < 1 { 99 return nil, &source.EmptyResultError{Word: word} 100 } 101 102 return &result, nil 103 }