golang TripAdvisor API接口封装与调用插件库TripAdvisor的使用
Golang TripAdvisor API接口封装与调用插件库TripAdvisor的使用
简介
这是一个用于Golang的TripAdvisor API封装库,可以方便地调用TripAdvisor API获取地点信息和评论数据。
安装
go get "github.com/mrbenosborne/tripadvisor-golang"
配置选项
SetKey
设置用于所有HTTP请求的TripAdvisor API密钥。
SetKey(string)
SetEndpoint
设置TripAdvisor端点,目前仅支持TripAdvisor API的第2版。
SetEndpoint(string)
SetLanguageCode
设置TripAdvisor响应的语言代码,支持的代码列表可以参考TripAdvisor API文档。
SetLanguageCode(string)
SetTimeout
设置所有HTTP请求的超时时间,默认为30秒。
SetTimeout(time.Duration)
使用示例
package main
import (
"context"
"log"
"github.com/mrbenosborne/tripadvisor-golang/pkg/tripadvisor"
)
func main() {
// 创建新客户端
tClient := tripadvisor.New(
tripadvisor.SetKey("XXXXXXXXXXXXXXXXXXXXXX"),
tripadvisor.SetLanguageCode("en_UK"),
)
// 获取地点评论(碎片大厦)
response, err := tClient.Location(context.Background(), 3539289)
if err != nil {
panic(err)
}
// 打印地点数据
log.Printf("%s - 总评论数: %s\n", response.Name, response.NumReviews)
for _, review := range response.Reviews {
log.Printf("评论:\n\t%s\n", review.Content)
}
}
示例响应
以下是Location响应的JSON格式示例输出:
{
"name": "The View from The Shard",
"num_reviews": "17349",
"category": {
"name": "attraction",
"localized_name": "Attraction"
},
"address_obj": {
"street1": "Joiner Street",
"city": "London",
"country": "United Kingdom",
"postalcode": "SE1",
"address_string": "Joiner Street, London SE1 England"
},
"latitude": "51.5045",
"longitude": "-0.0865",
"rating": "4.5",
"location_id": "3539289",
"trip_types": [
{
"name": "business",
"value": "318",
"localized_name": "Business"
},
{
"name": "couples",
"value": "7458",
"localized_name": "Couples"
},
{
"name": "solo",
"value": "960",
"localized_name": "Solo travel"
},
{
"name": "family",
"value": "3426",
"localized_name": "Family"
},
{
"name": "friends",
"value": "3138",
"localized_name": "Friends getaway"
}
],
"reviews": [
{
"id": "666623404",
"lang": "en",
"location_id": "3539289",
"published_date": "2019-04-15T03:54:07-0400",
"rating": 5,
"helpful_votes": "1",
"rating_image_url": "https://www.tripadvisor.com/img/cdsi/img2/ratings/traveler/s5.0-20236-5.svg",
"url": "https://www.tripadvisor.com/ShowUserReviews-g186338-d3539289-r666623404-The_View_from_The_Shard-London_England.html?m=20236#review666623404",
"travel_date": "2019-03",
"text": "Visiting The Shard (top level) is a must do in London, especially on not cloudy days. Wonderful view all around (attractions even seem to be small from there). No cheap (+- 30 GBP per person, but...",
"user": {
"username": "WimD94",
"user_location": {}
},
"title": "Beautiful view on sunny days"
},
{
"id": "666436956",
"lang": "en",
"location_id": "3539289",
"published_date": "2019-04-14T11:13:08-0400",
"rating": 5,
"helpful_votes": "1",
"rating_image_url": "https://www.tripadvisor.com/img/cdsi/img2/ratings/traveler/s5.0-20236-5.svg",
"url": "https://www.tripadvisor.com/ShowUserReviews-g186338-d3539289-r666436956-The_View_from_The_Shard-London_England.html?m=20236#review666436956",
"trip_type": "Business",
"travel_date": "2019-02",
"text": "I visited IntechOpen Office at The Shard and they could not have chosen a better workplace. The views from the top floor were spectacular.",
"user": {
"username": "MariaLorna1",
"user_location": {
"name": "Davis, California",
"id": "32283"
}
},
"title": "Beaautiful"
}
],
"percent_recommended": 82,
"review_rating_count": {
"1": "318",
"2": "477",
"3": "1802",
"4": "4798",
"5": "9680"
},
"photo_count": "11780",
"location_string": "London, England"
}
更多关于golang TripAdvisor API接口封装与调用插件库TripAdvisor的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang TripAdvisor API接口封装与调用插件库TripAdvisor的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
TripAdvisor API接口封装与调用插件库
TripAdvisor是一个全球知名的旅游评论和预订平台,提供丰富的API接口供开发者使用。下面我将介绍如何在Go语言中封装和调用TripAdvisor API。
1. 准备工作
首先,你需要在TripAdvisor开发者门户(https://developer-tripadvisor.com/)注册账号并获取API密钥。
2. 基础封装
以下是一个基础的TripAdvisor API封装示例:
package tripadvisor
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
const (
baseURL = "https://api.tripadvisor.com/api/partner/2.0/"
)
type Client struct {
apiKey string
httpClient *http.Client
}
func NewClient(apiKey string) *Client {
return &Client{
apiKey: apiKey,
httpClient: &http.Client{},
}
}
func (c *Client) makeRequest(endpoint string, params map[string]string) ([]byte, error) {
// 构建请求URL
reqURL, err := url.Parse(baseURL + endpoint)
if err != nil {
return nil, err
}
// 添加查询参数
query := reqURL.Query()
query.Set("key", c.apiKey)
for key, value := range params {
query.Set(key, value)
}
reqURL.RawQuery = query.Encode()
// 发送请求
resp, err := c.httpClient.Get(reqURL.String())
if err != nil {
return nil, err
}
defer resp.Body.Close()
// 检查响应状态
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API request failed with status code: %d", resp.StatusCode)
}
// 读取响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
3. 常用API方法封装
3.1 地点搜索
type Location struct {
LocationID string `json:"location_id"`
Name string `json:"name"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Address string `json:"address_obj"`
}
type LocationSearchResponse struct {
Data []Location `json:"data"`
}
func (c *Client) SearchLocations(query string, limit int) ([]Location, error) {
params := map[string]string{
"searchQuery": query,
"limit": fmt.Sprintf("%d", limit),
}
body, err := c.makeRequest("location/search", params)
if err != nil {
return nil, err
}
var response LocationSearchResponse
err = json.Unmarshal(body, &response)
if err != nil {
return nil, err
}
return response.Data, nil
}
3.2 获取地点详情
type LocationDetails struct {
LocationID string `json:"location_id"`
Name string `json:"name"`
Description string `json:"description"`
Rating float64 `json:"rating"`
RatingImage string `json:"rating_image_url"`
Address string `json:"address"`
Phone string `json:"phone"`
Website string `json:"website"`
PhotoCount int `json:"photo_count"`
ReviewCount int `json:"num_reviews"`
}
func (c *Client) GetLocationDetails(locationID string) (*LocationDetails, error) {
endpoint := fmt.Sprintf("location/%s", locationID)
body, err := c.makeRequest(endpoint, nil)
if err != nil {
return nil, err
}
var details LocationDetails
err = json.Unmarshal(body, &details)
if err != nil {
return nil, err
}
return &details, nil
}
3.3 获取地点评论
type Review struct {
ID string `json:"review_id"`
Rating float64 `json:"rating"`
Title string `json:"title"`
Text string `json:"text"`
UserName string `json:"user_name"`
UserAvatar string `json:"user_avatar"`
PublishDate string `json:"published_date"`
}
type ReviewsResponse struct {
Data []Review `json:"data"`
}
func (c *Client) GetLocationReviews(locationID string, limit int) ([]Review, error) {
endpoint := fmt.Sprintf("location/%s/reviews", locationID)
params := map[string]string{
"limit": fmt.Sprintf("%d", limit),
}
body, err := c.makeRequest(endpoint, params)
if err != nil {
return nil, err
}
var response ReviewsResponse
err = json.Unmarshal(body, &response)
if err != nil {
return nil, err
}
return response.Data, nil
}
4. 使用示例
package main
import (
"fmt"
"log"
"yourpackage/tripadvisor"
)
func main() {
// 初始化客户端
apiKey := "your_api_key_here"
client := tripadvisor.NewClient(apiKey)
// 搜索地点
locations, err := client.SearchLocations("Eiffel Tower", 5)
if err != nil {
log.Fatalf("Error searching locations: %v", err)
}
// 打印搜索结果
for _, loc := range locations {
fmt.Printf("Found location: %s (ID: %s)\n", loc.Name, loc.LocationID)
}
// 获取第一个地点的详情
if len(locations) > 0 {
details, err := client.GetLocationDetails(locations[0].LocationID)
if err != nil {
log.Fatalf("Error getting location details: %v", err)
}
fmt.Printf("\nDetails for %s:\n", details.Name)
fmt.Printf("Rating: %.1f\n", details.Rating)
fmt.Printf("Reviews: %d\n", details.ReviewCount)
fmt.Printf("Description: %s\n", details.Description)
// 获取评论
reviews, err := client.GetLocationReviews(locations[0].LocationID, 3)
if err != nil {
log.Fatalf("Error getting reviews: %v", err)
}
fmt.Println("\nRecent Reviews:")
for _, review := range reviews {
fmt.Printf("\n%s - %s\n", review.UserName, review.Title)
fmt.Printf("Rating: %.1f\n", review.Rating)
fmt.Printf("%s\n", review.Text)
}
}
}
5. 高级功能
5.1 添加缓存
type CachedClient struct {
client *Client
cache map[string][]byte
cacheTTL time.Duration
lastClean time.Time
}
func NewCachedClient(apiKey string, ttl time.Duration) *CachedClient {
return &CachedClient{
client: NewClient(apiKey),
cache: make(map[string][]byte),
cacheTTL: ttl,
lastClean: time.Now(),
}
}
func (c *CachedClient) makeRequest(endpoint string, params map[string]string) ([]byte, error) {
// 生成缓存键
cacheKey := endpoint + "?" + url.Values(params).Encode()
// 检查缓存
if data, ok := c.cache[cacheKey]; ok {
return data, nil
}
// 清理过期缓存
if time.Since(c.lastClean) > c.cacheTTL {
c.cache = make(map[string][]byte)
c.lastClean = time.Now()
}
// 调用原始API
data, err := c.client.makeRequest(endpoint, params)
if err != nil {
return nil, err
}
// 存入缓存
c.cache[cacheKey] = data
return data, nil
}
5.2 错误处理增强
type APIError struct {
StatusCode int
Message string
}
func (e APIError) Error() string {
return fmt.Sprintf("API error (status %d): %s", e.StatusCode, e.Message)
}
// 修改makeRequest方法
func (c *Client) makeRequest(endpoint string, params map[string]string) ([]byte, error) {
// ...之前的代码...
if resp.StatusCode != http.StatusOK {
errorBody, _ := ioutil.ReadAll(resp.Body)
var apiErr struct {
Message string `json:"message"`
}
json.Unmarshal(errorBody, &apiErr)
return nil, APIError{
StatusCode: resp.StatusCode,
Message: apiErr.Message,
}
}
// ...之后的代码...
}
6. 最佳实践
- 限流处理:TripAdvisor API有调用频率限制,建议实现限流机制
- 重试机制:对于临时性错误,实现自动重试
- 日志记录:记录API调用情况和错误
- 单元测试:为关键功能编写单元测试
- 上下文支持:添加context支持以便取消长时间运行的请求
7. 总结
本文介绍了如何在Go中封装TripAdvisor API,包括基础封装、常用API方法实现、缓存和错误处理增强等。通过合理的封装,可以使API调用更加简洁和安全,同时提高代码的可维护性。
你可以根据实际需求扩展这个基础封装,添加更多API端点支持或增强功能。记得在生产环境中添加适当的错误处理、日志记录和监控机制。