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  }