使用Golang和MongoDB構建 RESTful API

來源:互聯網
上載者:User

記錄一下建立 RESTful API使用 Go開發語言和 MongoDB後台資料庫

完整代碼 Github

image

安裝依賴

go get github.com/globalsign/mgo  // MongoDB的Go語言驅動go get github.com/gorilla/mux   // Go語言的http路由庫

API 結構預覽

app.go

package mainimport (    "fmt"    "net/http"    "github.com/gorilla/mux")func AllMovies(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func FindMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func CreateMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func UpdateMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func DeleteMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func main() {    r := mux.NewRouter()    r.HandleFunc("/movies", AllMovies).Methods("GET")    r.HandleFunc("/movies/{id}", FindMovie).Methods("GET")    r.HandleFunc("/movies", CreateMovie).Methods("POST")    r.HandleFunc("/movies", UpdateMovie).Methods("PUT")    r.HandleFunc("/movies", DeleteMovie).Methods("DELETE")    http.ListenAndServe(":8080", r)}

隨著後續路由的增加,需要重構一個這個檔案,仿照 beego的工程目錄,我們也分別建立對應的 controllers
routes,改造一下上面的代碼

  • 控制器

建立 controllers 檔案夾和對應的檔案 movies.go

movies.go

func AllMovies(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func FindMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func CreateMovie(w http.ResponseWriter, t *http.Request) {    fmt.Fprintln(w, "not implemented !")}func UpdateMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}func DeleteMovie(w http.ResponseWriter, r *http.Request) {    fmt.Fprintln(w, "not implemented !")}
  • 路由

建立一個 routes檔案夾,並建立對應的檔案 routes.go

routes.go

package routesimport (    "net/http"    "github.com/coderminer/restful/controllers"    "github.com/gorilla/mux")type Route struct {    Method     string    Pattern    string    Handler    http.HandlerFunc    Middleware mux.MiddlewareFunc}var routes []Routefunc init() {    register("GET", "/movies", controllers.AllMovies, nil)    register("GET", "/movies/{id}", controllers.FindMovie, nil)    register("POST", "/movies", controllers.CreateMovie, nil)    register("PUT", "/movies", controllers.UpdateMovie, nil)    register("DELETE", "/movies", controllers.DeleteMovie, nil)}func NewRouter() *mux.Router {    r := mux.NewRouter()    for _, route := range routes {        r.Methods(route.Method).            Path(route.Pattern).            Handler(route.Handler)        if route.Middleware != nil {            r.Use(route.Middleware)        }    }    return r}func register(method, pattern string, handler http.HandlerFunc, middleware mux.MiddlewareFunc) {    routes = append(routes, Route{method, pattern, handler, middleware})}

重構後的 app.go

package mainimport (    "net/http"    "github.com/coderminer/restful/routes")func main() {    r := routes.NewRouter()    http.ListenAndServe(":8080", r)}

Models

  • 建立 models 檔案夾和對應的檔案 db.go(資料層),封裝對MongoDB的封裝
package modelsimport (    "log"    "github.com/globalsign/mgo")const (    host   = "127.0.0.1:27017"    source = "admin"    user   = "user"    pass   = "123456")var globalS *mgo.Sessionfunc init() {    dialInfo := &mgo.DialInfo{        Addrs:    []string{host},        Source:   source,        Username: user,        Password: pass,    }    s, err := mgo.DialWithInfo(dialInfo)    if err != nil {        log.Fatalln("create session error ", err)    }    globalS = s}func connect(db, collection string) (*mgo.Session, *mgo.Collection) {    s := globalS.Copy()    c := s.DB(db).C(collection)    return s, c}func Insert(db, collection string, docs ...interface{}) error {    ms, c := connect(db, collection)    defer ms.Close()    return c.Insert(docs...)}func FindOne(db, collection string, query, selector, result interface{}) error {    ms, c := connect(db, collection)    defer ms.Close()    return c.Find(query).Select(selector).One(result)}func FindAll(db, collection string, query, selector, result interface{}) error {    ms, c := connect(db, collection)    defer ms.Close()    return c.Find(query).Select(selector).All(result)}func Update(db, collection string, query, update interface{}) error {    ms, c := connect(db, collection)    defer ms.Close()    return c.Update(query, update)}func Remove(db, collection string, query interface{}) error {    ms, c := connect(db, collection)    defer ms.Close()    return c.Remove(query)}
  • 商務邏輯層 models/movies.go
package modelsimport "github.com/globalsign/mgo/bson"type Movies struct {    Id          bson.ObjectId `bson:"_id" json:"id"`    Name        string        `bson:"name" json:"name"`    CoverImage  string        `bson:"cover_image" json:"cover_image"`    Description string        `bson:"description" json:"description"`}const (    db         = "Movies"    collection = "MovieModel")func (m *Movies) InsertMovie(movie Movies) error {    return Insert(db, collection, movie)}func (m *Movies) FindAllMovies() ([]Movies, error) {    var result []Movies    err := FindAll(db, collection, nil, nil, &result)    return result, err}func (m *Movies) FindMovieById(id string) (Movies, error) {    var result Movies    err := FindOne(db, collection, bson.M{"_id": bson.ObjectIdHex(id)}, nil, &result)    return result, err}func (m *Movies) UpdateMovie(movie Movies) error {    return Update(db, collection, bson.M{"_id": movie.Id}, movie)}func (m *Movies) RemoveMovie(id string) error {    return Remove(db, collection, bson.M{"_id": bson.ObjectIdHex(id)})}

控制器邏輯

  • CreateMovie
func CreateMovie(w http.ResponseWriter, r *http.Request) {    defer r.Body.Close()    var movie models.Movies    if err := json.NewDecoder(r.Body).Decode(&movie); err != nil {        responseWithJson(w, http.StatusBadRequest, "Invalid request payload")        return    }    movie.Id = bson.NewObjectId()    if err := dao.InsertMovie(movie); err != nil {        responseWithJson(w, http.StatusInternalServerError, err.Error())        return    }    responseWithJson(w, http.StatusCreated, movie)}

使用 Postmancurl進行測試

  • AllMovies
func AllMovies(w http.ResponseWriter, r *http.Request) {    defer r.Body.Close()    var movies []models.Movies    movies, err := dao.FindAllMovies()    if err != nil {        responseWithJson(w, http.StatusInternalServerError, err.Error())        return    }    responseWithJson(w, http.StatusOK, movies)}
  • FindMovie
func FindMovie(w http.ResponseWriter, r *http.Request) {    vars := mux.Vars(r)    id := vars["id"]    result, err := dao.FindMovieById(id)    if err != nil {        responseWithJson(w, http.StatusInternalServerError, err.Error())        return    }    responseWithJson(w, http.StatusOK, result)}

http://127.0.0.1:8080/movies/5b45ef3a9d5e3e197c15e774

  • UpdateMovie
func UpdateMovie(w http.ResponseWriter, r *http.Request) {    defer r.Body.Close()    var params models.Movies    if err := json.NewDecoder(r.Body).Decode(&params); err != nil {        responseWithJson(w, http.StatusBadRequest, "Invalid request payload")        return    }    if err := dao.UpdateMovie(params); err != nil {        responseWithJson(w, http.StatusInternalServerError, err.Error())        return    }    responseWithJson(w, http.StatusOK, map[string]string{"result": "success"})}
  • DeleteMovie
func DeleteMovie(w http.ResponseWriter, r *http.Request) {    vars := mux.Vars(r)    id := vars["id"]    if err := dao.RemoveMovie(id); err != nil {        responseWithJson(w, http.StatusBadRequest, "Invalid request payload")        return    }    responseWithJson(w, http.StatusOK, map[string]string{"result": "success"})}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.