Record the creation of RESTful APIs using Go
the development language and the MongoDB
background database
Full Code Github
Image
Installation dependencies
go get github.com/globalsign/mgo // MongoDB的Go语言驱动go get github.com/gorilla/mux // Go语言的http路由库
API Structure Preview
app.go
The 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)}
As the subsequent route increases, it is necessary to refactor a file, modeled after beego
the project directory, and we create the correspondingcontrollers
And routes
, change the code above
Create controllers
folders and corresponding filesmovies.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 !")}
Create a routes
folder and create the corresponding fileroutes.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})}
After the reconstructedapp.go
package mainimport ( "net/http" "github.com/coderminer/restful/routes")func main() { r := routes.NewRouter() http.ListenAndServe(":8080", r)}
Models
- Create a
models
folder and corresponding file db.go
(data layer), encapsulate the package to MongoDB
the
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, Colle ction) Defer Ms. Close () return C.insert (Docs ...)} Func FindOne (DB, collection string, query, selector, result interface{}) error {MS, c: = Connect (db, collection) de Fer 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) d Efer Ms. Close () return c.update (query, Update)}func Remove (DB, collection string, query interface{}) error {MS, c: = Connec T (db, collection) defer Ms. Close () return C.remove (query)}
- business Logic Layer
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, Collect Ion, 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 Mov IES ERR: = FindOne (db, Collection, Bson. m{"_id": Bson. Objectidhex (ID)}, nil, &result) return result, Err}func (M *movies) Updatemovie (movie Movies) error {return UPD Ate (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)})}
Controller logic
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)}
Postman
to use or curl
to test
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)}
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
func UpdateMovie(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() var params models.Movies if err := json.NewDecoder(r.Body).Decode(¶ms); 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"})}
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"})}