最近在看微服务,了解到一个微服务应用是多个后台服务组合起来的应用,这些个后台服务有自己的接口,自己的处理器,自己的数据库等。
概念看了很多,也有那么一丝丝理解,跟着一篇文档敲了一次代码,感觉下来还是一个单体应用,丝毫没有看到微服务的影子呀。。
代码如下:
`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,可以便于理解,我是越看越模糊了。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于