go 微服务框架_Go实战--微框架(Goji+Mongodb构建微服务)

生命不止,继续 go go go!!!

今天跟大家分享一个web微框架Goji.

Goji

What is Goji?

枸杞?

Goji is a HTTP request multiplexer, similar to net/http.ServeMux. It compares incoming requests to a list of registered Patterns, and dispatches to the Handler that corresponds to the first matching Pattern. Goji also supports Middleware (composable shared functionality applied to every request) and uses the standard context to store request-scoped values.

官网:
https://goji.io/

github地址:
https://github.com/goji/goji

Star:
577

文档地址:
https://godoc.org/goji.io

获取:
go get goji.io

示例:

package mainimport (    "fmt"    "net/http"    "goji.io"    "goji.io/pat")func hello(w http.ResponseWriter, r *http.Request) {    name := pat.Param(r, "name")    fmt.Fprintf(w, "Hello, %s!", name)}func main() {    mux := goji.NewMux()    mux.HandleFunc(pat.Get("/hello/:name"), hello)    http.ListenAndServe("localhost:8000", mux)}123456789101112131415161718192021

运行,浏览器访问:http://localhost:8000/hello/heyGoji
返回:Hello, heyGoji!

zenazn/goji

不要奇怪, zenazn/goji is new version of Goji,也就是一个作者。
This project has been superseded by a new version of Goji by the same author, which has very similar primitives and semantics, but has been updated to reflect several years of experience with this library and the surrounding Go ecosystem. This project is still well-loved and well-maintained, and will be for the foreseeable future, but new projects are encouraged to use goji.io instead.

Goji是一个用Go语言写的Web微框架。Goji的设计理念是简单、可组合性、自由。它具有以下特点:

  • 兼容net/http
  • url模式(同时支持 Sinatra 风格的 /foo/:bar 和 正则表达式)
  • 可重构中间件栈
  • 通过中间件和处理器处理上下文/环境对象
  • 自动支持 Einhorn、systemd等
  • 渐进停止,配合 Einhorn 可实现零下线时间的渐进重载

github地址:
https://github.com/zenazn/goji

Star:
3354

获取:
go get github.com/zenazn/goji

示例:

package mainimport (    "fmt"    "net/http"    "github.com/zenazn/goji"    "github.com/zenazn/goji/web")func hello(c web.C, w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])}func main() {    goji.Get("/hello/:name", hello)    goji.Serve()}123456789101112131415161718

运行:
2017/12/20 10:37:27.132172 Starting Goji on [::]:8000
2017/12/20 10:37:36.423659 [LAPTOP-MNU6522J/9tNAt5dWFL-000001] Started GET “/hello/heyGoji” from [::1]:19489
2017/12/20 10:37:36.423659 [LAPTOP-MNU6522J/9tNAt5dWFL-000001] Returning 200 in 0s

浏览器访问:http://localhost:8000/hello/heyGoji
返回:Hello, heyGoji!

应用

文件服务

package mainimport (    "fmt"    "net/http"    "github.com/zenazn/goji"    "github.com/zenazn/goji/web")func apiExampleHandler(context web.C, resp http.ResponseWriter, req *http.Request) {    fmt.Fprint(resp, "You've hit the API!")}func main() {    goji.Handle("/api", apiExampleHandler)    // Static file handler should generally be the last handler registered. Otherwise, it'll match every path.    // Be sure to use an absolute path.    staticFilesLocation := "./"    goji.Handle("/*", http.FileServer(http.Dir(staticFilesLocation)))    goji.Serve()}123456789101112131415161718192021222324

运行,浏览器输入http://localhost:8000/

Goji Restful Api

package mainimport (    "encoding/json"    "fmt"    "net/http"    "goji.io"    "goji.io/pat")type book struct {    ISBN    string "json:isbn"    Title   string "json:name"    Authors string "json:author"    Price   string "json:price"}var bookStore = []book{    book{        ISBN:    "0321774639",        Title:   "Programming in Go: Creating Applications for the 21st Century (Developer's Library)",        Authors: "Mark Summerfield",        Price:   "$34.57",    },    book{        ISBN:    "0134190440",        Title:   "The Go Programming Language",        Authors: "Alan A. A. Donovan, Brian W. Kernighan",        Price:   "$34.57",    },}func main() {    mux := goji.NewMux()    mux.HandleFunc(pat.Get("/books"), allBooks)    mux.HandleFunc(pat.Get("/books/:isbn"), bookByISBN)    mux.Use(logging)    http.ListenAndServe("localhost:8080", mux)}func allBooks(w http.ResponseWriter, r *http.Request) {    jsonOut, _ := json.Marshal(bookStore)    fmt.Fprintf(w, string(jsonOut))}func bookByISBN(w http.ResponseWriter, r *http.Request) {    isbn := pat.Param(r, "isbn")    for _, b := range bookStore {        if b.ISBN == isbn {            jsonOut, _ := json.Marshal(b)            fmt.Fprintf(w, string(jsonOut))            return        }    }    w.WriteHeader(http.StatusNotFound)}func logging(h http.Handler) http.Handler {    fn := func(w http.ResponseWriter, r *http.Request) {        fmt.Printf("Received request: %v", r.URL)        h.ServeHTTP(w, r)    }    return http.HandlerFunc(fn)}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

浏览器访问:
http://localhost:8080/books

返回:

// 20171220105345// http://localhost:8080/booksArray[2][  {    "ISBN": "0321774639",    "Title": "Programming in Go: Creating Applications for the 21st Century (Developer's Library)",    "Authors": "Mark Summerfield",    "Price": "$34.57"  },  {    "ISBN": "0134190440",    "Title": "The Go Programming Language",    "Authors": "Alan A. A. Donovan, Brian W. Kernighan",    "Price": "$34.57"  }]1234567891011121314151617

认证goji/httpauth
github地址:
https://github.com/goji/httpauth

获取:
go get github.com/goji/httpauth

package mainimport (    "net/http"    "github.com/goji/httpauth"    "github.com/zenazn/goji")func main() {    goji.Use(httpauth.SimpleBasicAuth("dave", "password"))    // myHandler requires HTTP Basic Auth to access    goji.Get("/thing", myHandler)    goji.Serve()}12345678910111213141516171819

Goji+Mongodb搭建微服务

出自:
http://goinbigdata.com/how-to-build-microservice-with-mongodb-in-golang/

golang中如何使用mongodb,我们之前多次介绍过了,可以翻看之前的博客。
启动mongodb server:

mongod.exe --dbpath d:mongodb_datadb1

直接上代码:

package mainimport (    "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)    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218

运行,使用curl post数据:

curl -X POST -H "Content-Type: application/json" -d '{"isbn": "0134190440", "title": "The Go Programming Language", "authors": ["Alan A. A. Donovan", "Brian W. Kernighan"], "price":   "$34.57"}' http://localhost:8080/books1

读取:

curl -H "Content-Type: application/json" http://localhost:8080/books1

返回:

[  {    "isbn": "0134190440",    "title": "The Go Programming Language",    "authors": [      "Alan A. A. Donovan",      "Brian W. Kernighan"    ],    "price": "$34.57"  }]1234567891011
b4ee6fc885d97bb71f112a6362ac9a90.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值