Porting golang yelp wrapper to v3-fusion-api
This commit is contained in:
173
yelp/yelp.go
Normal file
173
yelp/yelp.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package yelp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
rootURI = "https://api.yelp.com/"
|
||||
businessArea = "/v3/businesses"
|
||||
searchArea = "/v3/businesses/search"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnspecifiedLocation = errors.New("location must be specified")
|
||||
errBusinessNotFound = errors.New("business not found")
|
||||
)
|
||||
|
||||
// AuthOptions provide keys required for using the Yelp API. Find more
|
||||
// information here: https://www.yelp.com/developers/documentation/v3/authentication
|
||||
type AuthOptions struct {
|
||||
APIKey string // API Key from the yelp API access site.
|
||||
}
|
||||
|
||||
// Client manages all searches. All searches are performed from an instance of a client.
|
||||
// It is the top level object used to perform a search or business query. C
|
||||
type Client struct {
|
||||
Options *AuthOptions
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
// DoSimpleSearch performs a simple search with a term and location.
|
||||
func (client *Client) DoSimpleSearch(term, location string) (result SearchResult, err error) {
|
||||
|
||||
// verify the term and location are not empty
|
||||
if location == "" {
|
||||
return SearchResult{}, errUnspecifiedLocation
|
||||
}
|
||||
|
||||
// set up the query options
|
||||
params := map[string]string{
|
||||
"term": term,
|
||||
"location": location,
|
||||
}
|
||||
|
||||
// perform the search request
|
||||
_, err = client.makeRequest(searchArea, "", params, &result)
|
||||
if err != nil {
|
||||
return SearchResult{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DoSearch performs a complex search with full search options.
|
||||
func (client *Client) DoSearch(options SearchOptions) (result SearchResult, err error) {
|
||||
|
||||
// get the options from the search provider
|
||||
params, err := options.getParameters()
|
||||
if err != nil {
|
||||
return SearchResult{}, err
|
||||
}
|
||||
|
||||
// perform the search request
|
||||
_, err = client.makeRequest(searchArea, "", params, &result)
|
||||
if err != nil {
|
||||
return SearchResult{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetBusiness obtains a single business by name.
|
||||
func (client *Client) GetBusiness(name string) (result Business, err error) {
|
||||
statusCode, err := client.makeRequest(businessArea, name, nil, &result)
|
||||
if err != nil {
|
||||
// At some point the Yelp API stopped reporting 404s for missing business names, and
|
||||
// started reporting 400s :(
|
||||
if statusCode == 400 || statusCode == 404 {
|
||||
return Business{}, errBusinessNotFound
|
||||
}
|
||||
return Business{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// makeRequest is an internal/private API used to make underlying requests to the Yelp API.
|
||||
func (client *Client) makeRequest(area string, id string, params map[string]string, v interface{}) (statusCode int, err error) {
|
||||
// get the base url
|
||||
queryURI, err := url.Parse(rootURI)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// add the type of request we're making (search|business)
|
||||
queryURI.Path = area
|
||||
|
||||
if id != "" {
|
||||
queryURI.Path += "/" + id
|
||||
}
|
||||
|
||||
// Do request
|
||||
request, err := http.NewRequest("GET", queryURI.String(), nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
request.Header.Add("Authorization", "Bearer "+client.Options.APIKey)
|
||||
q := request.URL.Query()
|
||||
if params["term"] != "" {
|
||||
q.Add("term", params["term"])
|
||||
}
|
||||
if params["location"] != "" {
|
||||
q.Add("location", params["location"])
|
||||
}
|
||||
if params["limit"] != "" {
|
||||
q.Add("limit", params["limit"])
|
||||
}
|
||||
if params["offset"] != "" {
|
||||
q.Add("offset", params["offset"])
|
||||
}
|
||||
if params["sortby"] != "" {
|
||||
q.Add("sort_by", params["sortby"])
|
||||
}
|
||||
if params["categoryfilter"] != "" {
|
||||
q.Add("category_filter", params["categoryfilter"])
|
||||
}
|
||||
if params["locale"] != "" {
|
||||
q.Add("locale", params["locale"])
|
||||
}
|
||||
if params["longitude"] != "" {
|
||||
q.Add("longitude", params["longitude"])
|
||||
}
|
||||
if params["latitude"] != "" {
|
||||
q.Add("latitude", params["latitude"])
|
||||
}
|
||||
request.URL.RawQuery = q.Encode()
|
||||
|
||||
response, err := client.Client.Do(request)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if response != nil {
|
||||
return response.StatusCode, err
|
||||
}
|
||||
return 500, err
|
||||
}
|
||||
|
||||
// close the request when done
|
||||
defer response.Body.Close()
|
||||
|
||||
// ensure the request returned a 200
|
||||
if response.StatusCode != 200 {
|
||||
return response.StatusCode, errors.New(response.Status)
|
||||
}
|
||||
err = json.NewDecoder(response.Body).Decode(v)
|
||||
|
||||
return response.StatusCode, err
|
||||
}
|
||||
|
||||
// New will create a new yelp search client. All search operations should go through this API.
|
||||
func New(options *AuthOptions, httpClient *http.Client) *Client {
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
}
|
||||
|
||||
return &Client{
|
||||
Options: options,
|
||||
Client: httpClient,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user