这是我如何看待自己和其他人在Go中构建Web应用程序的示例。此代码未经测试,仅作为示例。它缺少导入,并且可能有错误。
编辑 添加了一个中间件示例。
main.go
package mainfunc main() { mongoDBDialInfo := &mgo.DialInfo{ Addrs: []string{config.DatabaseURL}, Timeout: 60 * time.Second, Database: config.DatabaseName, Username: config.DatabaseUsername, Password: config.DatabasePassword, } db, err := mgo.DialWithInfo(mongoDBDialInfo) if err != nil { log.Fatal("Cannot Dial Mongo: ", err) } defer db.Close() db.SetMode(mgo.Monotonic, true) phoneIndex := mgo.Index{ Key: []string{"pp"}, Unique: true, DropDups: true, Background: true, Sparse: true, } err = db.DB(config.DatabaseName).C("users").EnsureIndex(phoneIndex) if err != nil { panic(err) } mgoAdapter := mongo.NewAdapter(db, config.DatabaseName) deviceStore := mongo.NewDeviceStore(mgoAdapter) userStore := mongo.NewUserStore(mgoAdapter) loginController := controllers.NewLoginController(deviceStore) router := mux.NewRouter() router.HandleFunc("/login", middleware.AuthorizeUser(userStore)(http.HandlerFunc(loginController.Login)).Methods("POST") if err := http.ListenAndServe(":5000", router); err != nil { log.Fatal(err) }}控制器/login.go
package controllerstype LoginController struct { store DeviceStore}func NewLoginController(store stores.DeviceStore) *LoginController { return &LoginController{ store: store, }}func (c *LoginController) Login(w http.ResponseWriter, r *http.Request) { r.ParseForm() // Parses the request body device := r.Form.Get("device") data, err := c.store.FindByDevice(device) var respose models.Response if err != nil { w.WriteHeader(500) response = models.Response{Status: 500, Message: fmt.Sprintf("error: %s", err)} } else if data == nil { w.WriteHeader(404) response = models.Response{Status: 404, Message: "device not found"} } else { response = models.Response{Status: 200, Message: "device found", data: data} } // Write sets header to 200 if it hasn't been set already w.Write([]byte(utils.ResponseToString(response)))}store / stores.go
package storestype DeviceStore interface { FindByDevice(device string) (*models.Device, error)}type UserStore interface { FindByToken(token string) (*models.User, error)}中间件/auth.go
package middlewarefunc AuthorizeUser(store stores.UserStore) func(h *http.Handler) http.Handler { return func(h *http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Logic for authorizing user // Could also store user in the request context }) }}mongo / mongo.go
package mongotype Adapter struct { session *mgo.Session databaseName string}func NewAdapter(session *mgo.Session, dbName string) *Adapter { return &Adapter{session: session, databaseName: dbName}}type deviceStore struct { *Adapter}func NewDeviceStore(adapter *Adapter) stores.DeviceStore { return &deviceStore{adapter}}const devices = "devices"func (s *deviceStore) FindByDevice(d string) (*models.Device, err) { sess := s.session.copy() defer sess.close() var deviceID bson.ObjectId if bson.IsObjectIdHex(d) { deviceID = bson.ObjectIdHex(d) } var device models.Device err := db.DB(s.databaseName).C(devices).FindId(deviceID).One(&device) if err == mgo.ErrNotFound { return nil, nil } return &device, err}type userStore struct { *Adapter}const users = "users"func NewUserStore(adapter *Adapter) stores.UserStore { return &userStore{adapter}}func (s *userStore) GetUserByToken(token string) (*models.User, error) { sess := s.session.copy() defer sess.close() var user models.User err := db.DB(s.databaseName).C(users).Find(bson.M{"token": token}).One(&user) if err == mgo.ErrNotFound { return nil, nil } return &user, err}


