ต่อจากบทความ ที่แล้วนะครับ เขียน Go ดึงข้อมูลเกมส์ลดราคาของ Nintendo Switch ใช้งานเอง
รอบนี้เราจะมาลิส API กันก่อน ว่าจะทำอะไรกันต่อ
https://ec.nintendo.com/api/US/en/search/new?count=30&offset=0
https://ec.nintendo.com/api/JP/ja/search/ranking?count=10&offset=0
https://ec.nintendo.com/JP/ja/titles/70010000012325
โดยจะเห็นว่ายังมีเหลือ API สำหรับดึง Latest Released Game List แต่ละประเทศ
เราจะมาทำการแก้ไข package discount กันก่อน เพื่อให้ function ที่ดึงเกมส์กับราคาของเรารับค่า parameter เข้าไปเป็น string country code แล้วให้ return ออกมาเป็น URL แทน
ดังนั้นเราจะสร้าง map string ขึ้นมาใช้งาน
var API = map[string]string{"JP": "https://ec.nintendo.com/api/JP/ja/search/sales?count=30&offset=0","US": "https://ec.nintendo.com/api/US/en/search/sales?count=30&offset=0","GB": "https://ec.nintendo.com/api/GB/en/search/sales?count=10&offset=0","CA": "https://ec.nintendo.com/api/CA/en/search/sales?count=30&offset=0#Canada","AU": "https://ec.nintendo.com/api/AU/en/search/sales?count=10&offset=0#Australia","NZ": "https://ec.nintendo.com/api/NZ/en/search/sales?count=10&offset=0#NewZealand","CZ": "https://ec.nintendo.com/api/CZ/en/search/sales?count=10&offset=0#Czech","DK": "https://ec.nintendo.com/api/DK/en/search/sales?count=10&offset=0#Denmark","FI": "https://ec.nintendo.com/api/FI/en/search/sales?count=10&offset=0#Finland","GR": "https://ec.nintendo.com/api/GR/en/search/sales?count=10&offset=0#Greece","HU": "https://ec.nintendo.com/api/HU/en/search/sales?count=10&offset=0#Hungary","NO": "https://ec.nintendo.com/api/NO/en/search/sales?count=10&offset=0#Norway","PL": "https://ec.nintendo.com/api/PL/en/search/sales?count=10&offset=0#Poland","ZA": "https://ec.nintendo.com/api/ZA/en/search/sales?count=10&offset=0#SouthAfrica","SE": "https://ec.nintendo.com/api/SE/en/search/sales?count=10&offset=0#Sweden","DE": "https://ec.nintendo.com/api/DE/de/search/sales?count=10&offset=0","CH": "https://ec.nintendo.com/api/CH/de/search/sales?count=10&offset=0#Switzerland","FR": "https://ec.nintendo.com/api/FR/fr/search/sales?count=10&offset=0","BE-fr": "https://ec.nintendo.com/api/BE/fr/search/sales?count=10&offset=0#Belgium","IT": "https://ec.nintendo.com/api/IT/it/search/sales?count=10&offset=0","NL": "https://ec.nintendo.com/api/NL/nl/search/sales?count=10&offset=0","BE-nl": "https://ec.nintendo.com/api/BE/nl/search/sales?count=10&offset=0#Belgium","RU": "https://ec.nintendo.com/api/RU/ru/search/sales?count=30&offset=0","ES": "https://ec.nintendo.com/api/ES/es/search/sales?count=30&offset=0","MX": "https://ec.nintendo.com/api/MX/es/search/sales?count=30&offset=0#Mexico","CO": "https://ec.nintendo.com/api/CO/es/search/sales?count=10&offset=0#Columbia","AR": "https://ec.nintendo.com/api/AR/es/search/sales?count=10&offset=0#Argentina","CL": "https://ec.nintendo.com/api/CL/es/search/sales?count=10&offset=0#Chile","PE": "https://ec.nintendo.com/api/PE/es/search/sales?count=10&offset=0#Peru","PT": "https://ec.nintendo.com/api/PT/pt/search/sales?count=30&offset=0","BR": "https://ec.nintendo.com/api/BR/pt/search/sales?count=10&offset=0","HK": "https://ec.nintendo.com/api/HK/zh/search/sales?count=10&offset=0","KR": "https://ec.nintendo.com/api/KR/ko/search/sales?count=10&offset=0",}
และเราจะลบ
const (JP = iotaUSGB...)var api = []string{....}
ออกไป และทำการแก้ไข function GetDiscountGameFrom ให้รับ Argument เข้ามาเป็น string แทน เพื่อนำไป map กับ API ที่เราสร้างขึ้นมาก่อนหน้า
func GetDiscountGameFrom(api string) []byte {
จากนั้นเราจะไปแก้ไข package main ของเรา ก็คือ deshop.go เพื่อให้ code เราเรียกใช้งาน gorilla mux เพื่อเอาไปทำเป็น Resful API โดยจะให้
package mainimport ("fmt""net/http""github.com/aofiee/deshop/discount""github.com/gorilla/mux")func main() {handleRequest()}func handleRequest() {r := mux.NewRouter()r.HandleFunc("/discounts/{country}", gameList)http.Handle("/", r)http.ListenAndServe(":1234", nil)}func gameList(w http.ResponseWriter, r *http.Request) {param := mux.Vars(r)w.WriteHeader(http.StatusOK)response := discount.GetDiscountGameFrom(discount.API[param["country"]])fmt.Fprint(w, string(response))}
และเราจะทำการ Implement เพื่อให้
ก่อนอื่นเราจะไป rename package discount เป็นชื่อ eshop แทน เพื่อที่จะใช้ type structure บางตัวแทนกันได้
และเราจะทำการสร้าง function GetNewReleaseFromCountry ขึ้นมา โดยจะรับ parameter เป็น country code ในรูปแบบ string
func GetNewReleaseFromCountry(country string) {var lang = `en`if country == `JP` {lang = `jp`}newReleaseAPI := `https://ec.nintendo.com/api/` + country + `/` + lang + `/search/new?count=30&offset=0`data, err := http.Get(newReleaseAPI)if err != nil {return}if data.StatusCode != 200 {return}body, err := ioutil.ReadAll(data.Body)data.Body.Close()if err != nil {return}contents := Contents{}json.Unmarshal([]byte(body), &contents)fmt.Println("", contents)}
จะเห็นว่าในส่วนของการเตรียม Data structure ออกมาให้อยู่ในรูปแบบที่เราต้องการ มันซ้ำกับการดึง Game discount ดังนั้นเราจะมายุบส่วนที่มันซ้ำออกมาเป็นอีกหนึ่ง function ก็จะได้ว่า
func buildResult(contents Contents, country string) []byte {gameList := []GameDetail{}for _, game := range contents.Contents {price := getPriceWithCountryAndGameID(country, game.ID)FormalName := []rune(game.FormalName)gameFetch := GameDetail{ID: game.ID,Name: string(FormalName),Banner: game.HeroBannerURL,Prices: price,}gameList = append(gameList, gameFetch)}result, _ := json.MarshalIndent(gameList, "", " ")return result}
จากนั้นก็ไปยุบ code ข้างใน GetDiscountGameFrom และ GetNewReleaseFromCountry ซะ
func GetDiscountGameFrom(api string) []byte {data, err := http.Get(api)if err != nil {return nil}if data.StatusCode != 200 {return nil}body, err := ioutil.ReadAll(data.Body)data.Body.Close()if err != nil {return nil}contents := Contents{}json.Unmarshal([]byte(body), &contents)u, _ := url.Parse(api)country := parserURL(u)return buildResult(contents, country)}func GetNewReleaseFromCountry(country string) []byte {var lang = `en`if country == `JP` {lang = `jp`}newReleaseAPI := `https://ec.nintendo.com/api/` + country + `/` + lang + `/search/new?count=30&offset=0`data, err := http.Get(newReleaseAPI)if err != nil {return nil}if data.StatusCode != 200 {return nil}body, err := ioutil.ReadAll(data.Body)data.Body.Close()if err != nil {return nil}contents := Contents{}json.Unmarshal([]byte(body), &contents)return buildResult(contents, country)}
หลังจากนั้นเราจะมี ทำ function เพื่อ ดึง ranking กัน หลังจากดู result ที่ได้ และ code ที่เขียน ทำให้เห็นว่า new release, discount, ranking ใช้ api ร่วมกันได้หมดเลย งั้นเราจะยุบทั้งหมด มาใช้ตัวเดียวกัน โดยเราจะสร้าง function ขึ้นมาใหม่ชื่อว่า GetEndpoint โดยจะรับ parameter เป็น country string, service string และ return กลับไปเป็น []byte
//GetEndpoint funcfunc GetEndpoint(country string, service string) []byte {var lang = `en`if country == `JP` {lang = `ja`}var path stringswitch service {case `sale`:path = `sales?count=30&offset=0`breakcase `new`:path = `new?count=30&offset=0`breakcase `ranking`:path = `ranking?count=10&offset=0`break}endpoint := `https://ec.nintendo.com/api/` + country + `/` + lang + `/search/` + pathreturn getEndpointData(country, endpoint)}//getEndpointData funcfunc getEndpointData(country string, endpoint string) []byte {data, err := http.Get(endpoint)if err != nil {return nil}if data.StatusCode != 200 {return nil}body, err := ioutil.ReadAll(data.Body)data.Body.Close()if err != nil {return nil}contents := Contents{}json.Unmarshal([]byte(body), &contents)return buildResult(contents, country)}
และทำการลบ GetDiscountGameFrom และ GetNewReleaseFromCountry รวมทั้ง map string ทิ้งไปได้เลย ไม่เอามาใช้แล้ว
และทำการแก้ไข deshop.go ให้เรียกจาก function เดียว
package mainimport ("fmt""net/http""github.com/aofiee/deshop/eshop""github.com/gorilla/mux")func main() {handleRequest()}func handleRequest() {r := mux.NewRouter()r.HandleFunc("/discounts/{country}", gameList)r.HandleFunc("/new-release/{country}", newRelease)r.HandleFunc("/ranking/{country}", newRelease)http.Handle("/", r)http.ListenAndServe(":1234", nil)}func newRelease(w http.ResponseWriter, r *http.Request) {param := mux.Vars(r)w.WriteHeader(http.StatusOK)response := eshop.GetEndpoint(param["country"], `new`)fmt.Fprint(w, string(response))}func gameList(w http.ResponseWriter, r *http.Request) {param := mux.Vars(r)w.WriteHeader(http.StatusOK)response := eshop.GetEndpoint(param["country"], `sale`)fmt.Fprint(w, string(response))}func rankingList(w http.ResponseWriter, r *http.Request) {param := mux.Vars(r)w.WriteHeader(http.StatusOK)response := eshop.GetEndpoint(param["country"], `ranking`)fmt.Fprint(w, string(response))}
Quick Links
Legal Stuff