This is a creation in Article, where the information may have evolved or changed.
This is the technical translation, the original address (need to turn over the wall): http://www.goinggo.net/2013/12/sample-web-application-using-beego-and.html
Brief introduction
I felt very excited when I found the beego frame. It took me about 4 hours to port an existing WEB application to the framework and make some call extensions for end-to-end testing. I want to share this Beego-based site with you.
I built a sample WEB application with the following features:
- Implemented 2 Web calls to pull MongoDB data through a MGO drive.
- Use Envconfig to configure environment variables as parameters.
- Write test cases by Goconvey.
- Combined with my logging bag.
The code for this example can be found in the GitHub repository under the Goinggo account: Https://github.com/goinggo/beego-mgo.
You can pull and run it. It uses the public MongoDB database that I created in Mongolab. You will need to install Git and bazaar to ensure that you can use go get to install it on your system.
go get github.com/goinggo/beego-mgo
Use the footsteps in the Zscripts folder to quickly run or test your WEB application.
WEB Application code Structure
Let's look at the project structure and the features of different folders:
- App: Includes business, model, and service tiers.
- App/models: Data structures for business and service tiers.
- App/services: Used to provide basic functions for different services. Can be a function for a database or Web call.
- App/business: Called by the Controller and the function that handles business rules. A combination of multiple services calls can be used to implement functionality at a larger level.
- A pointcut for Controllers:url or Web API calls. The controller directly invokes the function of the business layer to process the request directly.
- Routes: A mapping for URL and controller code.
- Static: Used to hold statically-resourced resources such as scripts, CSS, and pictures.
- Test: You can use the tests run with go test.
- Utilities: Code that is used to support WEB applications. Sample and abstract code for database operations and panic processing.
- Views: Used to store template files.
- Zscripts: Scripts to help build, run, and test Web applications more easily.
controllers, models, and services
The code for these layers consists of a Web application. The idea behind my framework is to try to abstract code as a template. This requires me to implement a base controller package and a base service pack.
Base Controller Package
The base controller package consists of the default abstract controller behavior required by all controllers:
Type ( basecontroller struct { beego. Controller Services. Service }) func (this *basecontroller) Prepare () {this . UserId = "Unknown" tracelog. TRACE (this. UserId, "Before", "userid[%s] path[%s]", this. UserId, this. Ctx.Request.URL.Path) var err error this . Mongosession, err = MONGO. Copymonotonicsession (this. USERID) If err! = Nil { tracelog. Errorf (Err, this.) UserId, "before", this. Ctx.Request.URL.Path) This . Serveerror (Err) }}func (this *basecontroller) the Finish () { defer func () { if this. Mongosession! = Nil { MONGO. CloseSession (this. UserId, this. Mongosession) This . Mongosession = Nil } } () Tracelog.completedf (this. UserId, "Finish", this. Ctx.Request.URL.Path)}
A BaseController
new type named directly consists of type beego.Controller
and services.Service
embedding. This gives you direct access to all fields and methods of both types BaseController
, and directly manipulate these fields and methods.
Service Pack
Service packs are used to model the code required for all services:
Type ( Service struct { mongosession *mgo. Session UserId string }) func (this *service) dbaction (DatabaseName string, collectionname string, Mongocall MONGO. Mongocall) (err error) { return MONGO. Execute (this. UserId, this. Mongosession, databaseName, CollectionName, Mongocall)}
In the Service
type, the Mongo session and user ID are included. DBAction
The function provides an abstraction layer that runs MongoDB commands and queries.
Implement a Web call
Based on the base type and boilerplate functions, we can now implement a WEB call:
Buoy Controller
BuoyController
the type implements two binding BaseController
and business layer Web API calls. Our main concern is called Station
Web invocation.
Type buoycontroller struct { BC. Basecontroller}func (this *buoycontroller) station () { buoybusiness.station (&this. Basecontroller, this. GetString (": StationId"))}
BuoyController
the type is composed directly from a single BaseController
. With this combination, the BuoyController
Prepare
Finish
methods and all fields of the custom implementation are automatically obtained beego.Controller
.
The function is Station
distributed through the following route. stationId
as the last item in the URL. When this route is requested, an BuoyController
object is instantiated and the function is executed Station
.
beego.Router("/station/:stationId", &controllers.BuoyController{}, "get:Station")
The function calls the business Station
layer's code at the bottom to process the request.
Buoy Business
The Buoy business package implements BuoyController
the business layer. Let me see how the code for the business BuoyController
layer called by the function in is Station
:
Func Station (Controller *BC. Basecontroller, stationId string) { defer BC. Catchpanic (Controller, "station") TraceLog. STARTEDF (Controller. UserId, "station", "stationid[%s]", StationId) buoystation, err: = Buoyservice.findstation (&controller. Service, stationId) if err! = Nil { serveerror (err) return } controller. data["json"] = &buoystation controller. Servejson () tracelog.completed (Controller. UserId, "Station")}
You can see that the function of the business layer handles the logic of the Station
entire request. This function also uses the buoy service to handle the interaction with MongoDB.
Buoy Service
The Buoy Service package implements the interaction with MongoDB. Let's look at the code of the Station
function called by the function of the business layer FindStation
:
Func findstation (Service *services. Service, stationId String) (Buoystation *buoymodels.buoystation, err error) { defer helper. Catchpanic (&err, service. UserId, "Findstation") tracelog. STARTED (service. UserId, "Findstation") querymap: = Bson. m{"station_id": stationId} tracelog. TRACE (service. UserId, "Findstation", "Query:%s", MONGO. ToString (QueryMap)) buoystation = &buoymodels.buoystation{} Err = service. Dbaction (Config.database, "Buoy_stations", func (collection *mgo. Collection) Error { return Collection. Find (QueryMap). One (buoystation) }) if err! = Nil { Tracelog.completed_error (err, service. UserId, "Findstation") return buoystation, err } tracelog.completed (service. UserId, "Findstation") return buoystation, err}
The function FindStation
is used to prepare DBAction
queries and perform operations with MongoDB through functions.
End-to-end testing
We now have a URL that can be routed to a controller and the corresponding business and service layer logic, which can be tested in the following ways:
Func teststation (t *testing. T) { R, _: = http. Newrequest ("GET", "/station/42002", Nil) w: = Httptest. Newrecorder () Beego. BeeApp.Handlers.ServeHTTP (W, R) err: = struct { Error string } {} json. Unmarshal (W.body.bytes (), &err) convey ("Subject:test station endpoint\n", T, func () { convey ("Status Code should be + ", func () {So (W.code, Shouldequal, a) }) convey (" The Result should not being Empty ", func () {
so (W.body.len (), Shouldbegreaterthan, 0) }) convey ("The should is No Error in the Result", func () {so (Len (Err. Error), shouldequal, 0})} )}
The test creates a virtual call to a route. This is great because we don't really have to launch a WEB app to test the code. With Goconvey we are able to create very elegant outputs and are easy to read.
The following is a sample of a test failure:
Subject: Test Station Endpoint Status Code Should Be 200 ✘ The Result Should Not Be Empty The Should Be No Error In The Result ✘Failures:* /Users/bill/Spaces/Go/Projects/src/github.com/goinggo/beego-mgo/test/endpoints/buoyEndpoints_test.go Line 35:Expected: '200'Actual: '400'(Should be equal)* /Users/bill/Spaces/Go/Projects/src/github.com/goinggo/beego-mgo/test/endpoints/buoyEndpoints_test.go Line 37:Expected: '0'Actual: '9'(Should be equal)3 assertions thus far--- FAIL: TestStation-8 (0.03 seconds)
Here is an example of a successful test:
Subject: Test Station Endpoint Status Code Should Be 200 The Result Should Not Be Empty The Should Be No Error In The Result 3 assertions thus far--- PASS: TestStation-8 (0.05 seconds)
Conclusion
Take the time to download the project and see for yourself. I try my best to give you a clear view of the focus I want to show you. The Beego framework allows you to implement abstraction and boilerplate code very easily, and integrate go testing, running, and deployment in the Go style.