Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
来源:互联网 发布:如何开通淘宝直播 编辑:程序博客网 时间:2024/04/29 10:54
生命不止,继续 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)}
运行,浏览器访问: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()}
运行:
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()}
运行,浏览器输入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\n", r.URL) h.ServeHTTP(w, r) } return http.HandlerFunc(fn)}
浏览器访问:
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" }]
认证
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()}
Goji+Mongodb搭建微服务
出自:
http://goinbigdata.com/how-to-build-microservice-with-mongodb-in-golang/
golang中如何使用mongodb,我们之前多次介绍过了,可以翻看之前的博客。
启动mongodb server:
mongod.exe --dbpath d:\mongodb_data\db
直接上代码:
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) }}
运行,使用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/books
读取:
curl -H "Content-Type: application/json" http://localhost:8080/books
返回:
[ { "isbn": "0134190440", "title": "The Go Programming Language", "authors": [ "Alan A. A. Donovan", "Brian W. Kernighan" ], "price": "$34.57" }]
- Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
- Go实战--golang中使用MongoDB(mgo)
- Golang 微服务框架 Go kit 介绍
- Go实战--golang中使用echo框架、MongoDB、JWT搭建REST API(labstack/echo、gopkg.in/mgo.v2、dgrijalva/jwt-go)
- Go实战--golang中使用go-spew(davecgh/go-spew)
- Go实战--golang使用ssl连接MongoDB(mgo)
- Go实战--golang中使用echo框架中JSONP(labstack/echo)
- Go实战--golang中使用echo框架中的cors(labstack/echo、rs/cors)
- Go实战--golang中使用echo框架中的HTTP/2、Server Push(labstack/echo、golang.org/x/net/http2)
- go 构建微服务程序
- Go实战--golang中使用JWT(JSON Web Token)
- Go实战--golang中使用markdown(russross/blackfriday)
- Go实战--golang中使用firebase实时数据库(zabawaba99/firego)
- Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
- [goa]golang微服务框架学习--安装使用
- Go实战--golang中使用redis(redigo和go-redis/redis)
- Go实战--golang中使用WebSocket实时聊天室(gorilla/websocket、nkovacs/go-socket.io)
- Go实战--golang中使用echo和MySQL搭建api(labstack/echo、go-sql-driver/mysql)
- 用正则表达式-验证邮箱
- maven 下载依赖
- 基于vue-cli的eslint设置
- 倒计时 Timer和handler
- 消息中间件kafka+zookeeper集群部署、测试与应用
- Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
- 144. Binary Tree Preorder Traversal
- 导入发信息的架包进行发信息
- 解决绕过android下apk使用usb设备权限查询相应问题,自动获取usb权限
- 前端常用的网站插件
- 异步请求无法重定向的原因,response。sendRedirect原理
- 关于jsp的一些东西(全转载)
- NPM- Cannot find module 'xxxxx'
- 课工场荣获中国网2017年综合实力教育集团