最近在看微服务,了解到一个微服务应用是多个后台服务组合起来的应用,这些个后台服务有自己的接口,自己的处理器,自己的数据库等。
概念看了很多,也有那么一丝丝理解,跟着一篇文档敲了一次代码,感觉下来还是一个单体应用,丝毫没有看到微服务的影子呀。。
代码如下:
`package main`
`import ( `
`"encoding/json"`
`"fmt"`
`"log"`
`"net/http"`
`"goji.io"`
`"goji.io/pat"`
`"gopkg.in/mgo.v2"`
`"gopkg.in/mgo.v2/bson"`
`)`
`func ErrorWithJSON(w http.ResponseWriter, message string, code` `int``) { `
`w.Header().Set(``"Content-Type"``,` `"application/json; charset=utf-8"``)`
`w.WriteHeader(code)`
`fmt.Fprintf(w,` `"{message: %q}"``, message)`
`}`
`func ResponseWithJSON(w http.ResponseWriter, json []byte, code` `int``) { `
`w.Header().Set(``"Content-Type"``,` `"application/json; charset=utf-8"``)`
`w.WriteHeader(code)`
`w.Write(json)`
`}`
`type Book` `struct` `{ `
`ISBN string `json:``"isbn"
`Title string `json:``"title"
`Authors []string `json:``"authors"
`Price string `json:``"price"
`}`
`func main() { `
`session, err := mgo.Dial(``"localhost"``)`
`if` `err != nil {`
`panic(err)`
`}`
`defer session.Close()`
`session.SetMode(mgo.Monotonic,` `true``)`
`ensureIndex(session)`
`mux := goji.NewMux()`
`mux.HandleFunc(pat.Get(``"/books"``), allBooks(session))`
`mux.HandleFunc(pat.Post(``"/books"``), addBook(session))`
`mux.HandleFunc(pat.Get(``"/books/:isbn"``), bookByISBN(session))`
`mux.HandleFunc(pat.Put(``"/books/:isbn"``), updateBook(session))`
`mux.HandleFunc(pat.Delete(``"/books/:isbn"``), deleteBook(session))`
`http.ListenAndServe(``"localhost:8080"``, mux)`
`}`
`func ensureIndex(s *mgo.Session) { `
`session := s.Copy()`
`defer session.Close()`
`c := session.DB(``"store"``).C(``"books"``)`
`index := mgo.Index{`
`Key: []string{``"isbn"``},`
`Unique:` `true``,`
`DropDups:` `true``,`
`Background:` `true``,`
`Sparse:` `true``,`
`}`
`err := c.EnsureIndex(index)`
`if``err != nil {`
`panic(err)`
`}`
`}`
`func allBooks(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`c := session.DB(``"store"``).C(``"books"``)`
`var books []Book`
`err := c.Find(bson.M{}).All(&books)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed get all books: "``, err)`
`return`
`}`
`respBody, err := json.MarshalIndent(books,` `""``,` `" "``)`
`if` `err != nil {`
`log``.Fatal(err)`
`}`
`ResponseWithJSON(w, respBody, http.StatusOK)`
`}`
`}`
`func addBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`var book Book`
`decoder := json.NewDecoder(r.Body)`
`err := decoder.Decode(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Incorrect body"``, http.StatusBadRequest)`
`return`
`}`
`c := session.DB(``"store"``).C(``"books"``)`
`err = c.Insert(book)`
`if` `err != nil {`
`if` `mgo.IsDup(err) {`
`ErrorWithJSON(w,` `"Book with this ISBN already exists"``, http.StatusBadRequest)`
`return`
`}`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed insert book: "``, err)`
`return`
`}`
`w.Header().Set(``"Content-Type"``,` `"application/json"``)`
`w.Header().Set(``"Location"``, r.URL.Path+``"/"``+book.ISBN)`
`w.WriteHeader(http.StatusCreated)`
`}`
`}`
`func bookByISBN(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`c := session.DB(``"store"``).C(``"books"``)`
`var book Book`
`err := c.Find(bson.M{``"isbn"``: isbn}).One(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed find book: "``, err)`
`return`
`}`
`if` `book.ISBN ==` `""` `{`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`respBody, err := json.MarshalIndent(book,` `""``,` `" "``)`
`if` `err != nil {`
`log``.Fatal(err)`
`}`
`ResponseWithJSON(w, respBody, http.StatusOK)`
`}`
`}`
`func updateBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`var book Book`
`decoder := json.NewDecoder(r.Body)`
`err := decoder.Decode(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Incorrect body"``, http.StatusBadRequest)`
`return`
`}`
`c := session.DB(``"store"``).C(``"books"``)`
`err = c.Update(bson.M{``"isbn"``: isbn}, &book)`
`if` `err != nil {`
`switch` `err {`
`default``:`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed update book: "``, err)`
`return`
`case` `mgo.ErrNotFound:`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`}`
`w.WriteHeader(http.StatusNoContent)`
`}`
`}`
`func deleteBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`c := session.DB(``"store"``).C(``"books"``)`
`err := c.Remove(bson.M{``"isbn"``: isbn})`
`if` `err != nil {`
`switch` `err {`
`default``:`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed delete book: "``, err)`
`return`
`case` `mgo.ErrNotFound:`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`}`
`w.WriteHeader(http.StatusNoContent)`
`}`
`}`
希望各位大佬给点入门指导或者建议,最好有代码 demo,可以便于理解,我是越看越模糊了。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于