Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
生命不止,继续 go go go!!! 今天跟大家分享一个web微框架Goji. GojiWhat 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. 官网: github地址: Star: 文档地址: 获取: 示例: package main
import (
"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 zenazn/goji不要奇怪, zenazn/goji is new version of Goji,也就是一个作者。 Goji是一个用Go语言写的Web微框架。Goji的设计理念是简单、可组合性、自由。它具有以下特点:
github地址: Star: 获取: 示例: package main
import (
"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,c.URLParams["name"])
}
func main() {
goji.Get("/hello/:name",hello)
goji.Serve()
}
运行: 浏览器访问:http://localhost:8000/hello/heyGoji 应用文件服务 package main
import (
"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 main
import (
"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",}
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: %vn",r.URL)
h.ServeHTTP(w,r)
}
return http.HandlerFunc(fn)
}
浏览器访问: 返回: // 20171220105345
// http://localhost:8080/books
Array[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,"Price": "$34.57"
}
]
认证 获取: package main
import (
"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搭建微服务出自: golang中如何使用mongodb,我们之前多次介绍过了,可以翻看之前的博客。 mongod.exe --dbpath d:mongodb_datadb
直接上代码: 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,"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) {
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,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) {
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,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,http.StatusOK)
}
}
func updateBook(s *mgo.Session) func(w http.ResponseWriter,"isbn")
var book Book
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&book)
if err != nil {
ErrorWithJSON(w,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,http.StatusInternalServerError)
log.Println("Failed update book: ",err)
return
case mgo.ErrNotFound:
ErrorWithJSON(w,http.StatusNotFound)
return
}
}
w.WriteHeader(http.StatusNoContent)
}
}
func deleteBook(s *mgo.Session) func(w http.ResponseWriter,"isbn")
c := session.DB("store").C("books")
err := c.Remove(bson.M{"isbn": isbn})
if err != nil {
switch err {
default:
ErrorWithJSON(w,http.StatusInternalServerError)
log.Println("Failed delete book: ",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" }
]
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |