Build microservices using Golang and MongoDB

Umermansoor Github’s Python microservices have been transformed into Golang microservices, a total of 4 microservices

  • Movie Service: Basic information about a Movie, title, rating, etc
  • ShowTimes Service: Information about movie release dates
  • Booking Service: Information about a movie subscription
  • User Service: User information

Source making

requirements

  • Golang
  • mux
  • MongoDB

API and document

Each service is independent from each other, with separate routing and database. Communication between each service is through HTTP JSON, and the return result of API of each service is also JSON type. We can refer to using Golang and MongoDB to build RESTful API to extract the common things between each service. Independent of the service and available for service invocation

  • The result returned is encapsulated

helper/utils.go

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)
}

Copy the code
  • Basic data Entity

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"`}Copy the code
  • About database encapsulation

Dao /db.go. For details, see Encapsulation of mgo’s basic operations on MongoDB

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)
}
...
Copy the code

service

Specific logic of each service Specific reference Use Golang and MongoDB to build RESTful apis

  • User Service(port 8000)
  • Movie Service(port 8001)
  • ShowTimes Service(port 8002)
  • Booking Service(port 8003)

Service communication

When querying the Movie information subscribed by a User, the User is first queried through the User Service, the subscription information of the User is queried through Booking Service according to the User name, and the corresponding Movie information is queried through the Movie Service, all of which are through HTTP communication

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)
	iferr ! = nil { helper.ResponseWithJson(w, http.StatusBadRequest,"invalid request by name "+name)
		return
	}

	defer res.Body.Close()
	result, err := ioutil.ReadAll(res.Body)
	iferr ! = 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")}Copy the code