根據 umermansoor github的 Python
版本的微服務改形成 Golang
版本
一共有4個微服務git
源碼 Githubgithub
各個服務之間相互獨立,單獨的路由和單獨的數據庫,各個服務之間的通訊是經過 HTTP JSON
,每一個服務的API的返回結果也是JSON類型,能夠參考 使用Golang和MongoDB構建 RESTful API,提取出各個服務之間共同的東西,獨立於服務以外,供服務調用golang
helper/utils.go
mongodb
func ResponseWithJson(w http.ResponseWriter, code int, payload interface{}) {
response, _ := json.Marshal(payload)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
w.Write(response)
}
複製代碼
models/models.go
數據庫
type User struct {
Id string `bson:"_id" json:"id"`
Name string `bson:"name" json:"name"`
}
type Movie struct {
Id string `bson:"_id" json:"id"`
Title string `bson:"title" json:"title"`
Rating float32 `bson:"rating" json:"rating"`
Director string `bson:"director" json:"director"`
}
type ShowTimes struct {
Id string `bson:"_id" json:"id"`
Date string `bson:"date" json:"date"`
Movies []string `bson:"movies" json:"movies"`
}
type Booking struct {
Id string `bson:"_id" json:"id"`
Name string `bson:"name" json:"name"`
Books []BookInfo `bson:"books" json:"books"`
}
type BookInfo struct {
Date string `bson:"date" json:"date"`
Movies []string `bson:"movies" json:"movies"`
}
type Result struct {
Name string `json:"name"`
Books []ResultInfo `json:"books"`
}
type ResultInfo struct {
Date string `json:"date"`
Movies []Movie `json:"movies"`
}
複製代碼
dao/db.go
,具體的請參考 對 mgo關於MongoDB的基礎操做的封裝json
func Insert(db, collection string, docs ...interface{}) error {
ms, c := connect(db, collection)
defer ms.Close()
return c.Insert(docs...)
}
func FindOne(db, collection string, query, selector, result interface{}) error {
ms, c := connect(db, collection)
defer ms.Close()
return c.Find(query).Select(selector).One(result)
}
...
複製代碼
各個服務具體的邏輯具體的參考 使用Golang和MongoDB構建 RESTful APIbash
查詢某個用戶的訂閱的電影信息時,須要先經過 User Service
服務查詢這個用戶,根據用戶名經過 Booking Service
查詢用戶的訂閱信息,而後經過 Movie Service
服務查詢對應的電影的信息,都是經過 HTTP
通訊app
params := mux.Vars(r)
name := params["name"]
var user models.User
if err := dao.FindOne(db, collection, bson.M{"_id": name}, nil, &user); err != nil {
helper.ResponseWithJson(w, http.StatusBadRequest, "invalid request")
return
}
res, err := http.Get("http://127.0.0.1:8003/booking/" + name)
if err != nil {
helper.ResponseWithJson(w, http.StatusBadRequest, "invalid request by name "+name)
return
}
defer res.Body.Close()
result, err := ioutil.ReadAll(res.Body)
if err != nil {
helper.ResponseWithJson(w, http.StatusBadRequest, "invalid request of booking by name "+name)
return
}
var booking models.Booking
var resResult models.Result
resResult.Name = name
var resInfo models.ResultInfo
if err := json.Unmarshal(result, &booking); err == nil {
for _, book := range booking.Books {
resInfo.Date = book.Date
for _, movie := range book.Movies {
res, err := http.Get("http://127.0.0.1:8001/movies/" + movie)
if err == nil {
result, err := ioutil.ReadAll(res.Body)
if err == nil {
var movie models.Movie
if err := json.Unmarshal(result, &movie); err == nil {
resInfo.Movies = append(resInfo.Movies, movie)
}
}
}
}
resResult.Books = append(resResult.Books, resInfo)
}
helper.ResponseWithJson(w, http.StatusOK, resResult)
} else {
helper.ResponseWithJson(w, http.StatusBadRequest, "invalid request")
}
複製代碼