Use Golang+mongodb to build your first site

Source: Internet
Author: User
Tags token identifier
This is a creation in Article, where the information may have evolved or changed.

Many people recommend mean to develop the site. Mean is M:mongodb,e:expressjs, a:angular the last N:nodejs. But if you personally feel the JS nested callback, you will want to change the other way. Although it is possible to use promise and other frameworks to crack deep nesting, but after all, is not supported by the language itself.

Why use Golang? Because Golang is a static language with dynamic language features. Grammar is simple, grammar sugar is to minimize grammar. When compiling, you can get rid of many errors. You don't have to run like a dynamic language to fall into a pit.

Martini was found in Golang's numerous web frameworks. He later felt that the framework had used too much reflection to influence efficiency, and that it had written another framework or "middleware", called Negroni, as the author had said. Specific development reasons to see here. It may be the author's love of drinking the frame he wrote was called a wine name. Margini This framework is written by the author inspired by the Expressjs. So it is very similar in many things, such as the binding syntax of the route, the binding syntax of the class middleware, and so on. Also seen Golang other frameworks such as Revel, there are a lot of cool features, and a lot of one-stop support, but because Martini flexible decision to choose Margini.

Database MongoDB

Database, for the consistency of things and data requirements are not so strong, or choose a relatively simple NoSQL database is more appropriate. So, just use MongoDB. Maybe it shouldn't be used in rigorous work. However, MongoDB can be as simple as just writing the HTTP POST JSON data directly into the database. If JSON is simple, you don't have to do any design at all! Of course, the actual work is not possible. What we are discussing is just such a feasibility.

Then we'll start using Martini (Golang) and MongoDB to build a Web APP. The name of the app is called Navigator (the Navigator). is used to accept, store, and analyze user feedback and user questions, such as user feedback from various customers. The contextual information for these issues is very limited. So we let the user call the Navigator interface through the mobile client to commit the relevant contextual information at the same time. Some of the basics about Golang are not discussed here. Go get get Martini, download MongoDB. Then use the command to run up MongoDB. Give DB a name: NDB. Then fill in a document inside. MongoDB If you do not insert a document, then the database is not actually created. This document is a JSON. The format is:

{"Feedbackcode": "123", "username": "", "Phonenum": "", "DeviceInfo": {"SystemType": "", "Systemver": "", "AppVer": ""}, "ImageList": [], "desc": "Testing", "Feedbacktype": "", "Other": ""}

Use feedbackCode to mark a unique feedback. The problem with the database is completely solved.

Directory Structure of the site

Let's start our site section below. First look at the directory structure:

Navigator
| ——— conf
|-———— –conf.go # configuration information
| ————— –configerror.go # error name
| ——— Controllers
| ————— –feedbackcontroller.go
| ————— –indexcontroller.go
|–––models
|––––––feedbackmodel.go
server.go

The MVC pattern of this directory-structured typical rest API is embodied. We don't need to deal with the view, which is the HTML thing. However, the model and controller are differentiated by the display. The view is still there, but it is the JSON after the last render.

Run up

First, let's get our web app up and running. Add the following code to SERVER.GO:

Package Mainimport "Github.com/go-martini/martini" Func Main () {  m: = Martini. Classic ()  m.get ("/", func () string {    return "Hello world!"  })  M.run ()}

go run server.gocommand to get the Web app up and running. The default is to run on Port 3000. On the page can only see the bare few words Hello world! martini.Classic() After the call, Martini will provide some tools for you by default. One of the most important of these is routing . After this, you can use m.Get("/", func()string{return "Hello, world!"} to specify what path maps to what processing method. The last Call m.Run() method runs the entire app on Port 3000.

Now it's time to really develop the app. First we need to have a simple demand analysis of what we are going to do. As mentioned earlier, the user can use this API to send feedback up, and then in another interface to display the content in the form of a list. The need is so simple. Let's step through these features below.

Controllers

Because of the insert of a feedback, the amount of information required is still very large. We use the Post method to send the required feedback data. So, we need a post path and handler function Handler(hereafter called Handler).

M.post ("/", Func (req *http. Request) string{    //Remove parameters from req, insert INTO database})

The interface of the real feedback list only needs to respond to a GET request. So is a get path and handler. It should look like this:

M.get ("/", func () string {//) assuming that the last dictionary is converted to a JSON string return []map[string]string{map[string]string{"Feedbackcode": "1", " Username ":" John "},    map[string]string{" Feedbackcode ":" 2 "," username ":" Tony "}}}

The handler listed above are some simulations of adding data and data lists to the API. The following begins the formal writing of the controller.

List Controller

Look at the code first, and then explain it in detail:

Package Controllersimport (//"FMT" "FMT" "Github.com/martini-contrib/render" "navigator/conf" "Navigator/models" "net /http ") type Feedbackcontroller struct {}func (c *feedbackcontroller) feedbacklist (req *http. Request, R render. Render) {f: = new (models. Feedbackmodel) R.json ($, map[string]interface{}{"data": F.modellist (Nil)})}

Introduced github.com/martini-contrib/render , render is a rendered package. If you have an HTML view, you can convert the data to the data available in the HTML template. We use this package here to convert the dictionary into JSON data. r.JSON(200, map[string]interface{}{"data": f.ModelList(nil)})in 200, is the status code. The dictionary that needs to be converted is a string that is a dictionary of values for the Key,model list.

Here you can learn some of the feedback model classes:

Type deviceinfo struct {systemtype string ' JSON: "SystemType" '    //iOS or Androidsystemver  string ' JSON: "Systemve Rsion "'//system version eg, iOS 9.1AppVer     string ' JSON: ' appversion '    ///app version eg, 2.9.0}type Feedbackmode L struct {feedbackcode string     ' JSON: "Feedbackcode" ' UserName     string     ' JSON: "UserName" ' Phonenum     String     ' JSON: "Phonenum" ' deviceinfo   deviceinfo ' JSON: "DeviceInfo" ' ImageList    []string   ' JSON: " ImageList "' Desc         string     ' JSON:" description "' Feedbacktype string     ' JSON:" Feedbacktype "'//Normal Feedback or a problem in Useother        string     ' JSON: "Other" '        //Other infomation}

At the very beginning, the JSON data definition can be defined as the above code in the Model class definition of Golang. Marked with "'" is the relationship between the model field and the key of the JSON string in the process of converting the model to JSON strings. Finally, the Controller's function is to process the requested data, that is, the controller's method as a get or post handler. The two need to be correlated:

Package main Import (//Other Packages    "navigator/controllers") Func main () {varm =Martini. Classic ()varR =Martini. Newrouter () Feedbackcontroller:=New(controllers. Feedbackcontroller) R.get ("/nav/feedback", Feedbackcontroller.feedbacklist) r.post ("/nav/feedback", Feedbackcontroller.feedback) m.action (r.handle) m.runonaddr (": 9090")}

Here r.Get("/nav/feedback", feedbackController.FeedbackList) , the previous access path has been modified. /nav/feedback is the name of an item on the path that is abbreviated as a qualifier. Because a direct call to feedback is likely to be mixed up with other interfaces of the same name. That is, the pollution of the interface. So add a project name to avoid this problem. feedbackController := new(controllers.FeedbackController)initializes the Feedbackcontroller. feedbackControllerbind the method FeedbackList and the access path together. GET http access and FeedbackList method bindings,POST http access and Feedback method bindings. Finally m.RunOnAddr(":9090") replaced the previously used m.Run() . The app was previously running on Port 3000. The m.RunOnAddr(":9090") app will now run on Port 9090. That is, you can use this statement to make an app run port.

Models and MongoDB

Processing MongoDB We use MGO this library. Golang though for so many years already. Also out of so many star products. However, it is still possible to say no to the mature libraries that deal with MongoDB. There is nothing like Python, Nodejs and other languages such as the library so rich. There are standards, and there are many libraries developed by other developers on GitHub. The Golang is the relatively usable of the library compared to MgO.

When the feedback JSON string of a POST request is passed in, it is converted to an FeedbackModel object. Golang's JSON library will help us do that. json.Unmarshal([]byte(dict), &f)The Unmarshal method here converts a JSON string into a Feedbackmodel object. A factory method needs to be used here. Generates a model object, and the object should be a rich model object . The following model object will have the ability to manipulate the database, add, delete, change, check the method. Code:

string) *Feedbackmodel {    var  f Feedbackmodel    err:= json. Unmarshal ([]byte(dict), &f)    if err! = Nil        {return  Nil    }    return &F}

The above code will be used in the library "encoding/json" . This method is used to convert the feedback JSON string to a Feedbackmodel object when it is received. As mentioned above, this model will be added to the method of database operation. Then we can perform the operation of the data through the model obtained by the JSON string. Code:

Func (M *feedbackmodel) modellist (conditions map[string]string) []feedbackmodel {confinstance:=Conf. Configinstance () Mgouri:=Conf. Configinstance (). Mongodbconnectionstring ()//var f feedbackmodelSession, Err: =MgO. Dial (Mgouri)ifErr! =Nil {fmt. Printf ("can not connect to server%v\n", Err) Panic (ERR)} defer session. Close ()varFeedbackmodellist []feedbackmodel collection:= Session. DB (Confinstance.dbname). C"Feedback") Err= collection. Find (conditions). All (&feedbackmodellist)returnFeedbackmodellist}func (M*feedbackmodel) Getmodel (modelidstring) (*Feedbackmodel, error) {    //part of the code is omitted hereCollection: = Session. DB (Confinstance.dbname). C"Feedback") Err= collection. Find (Bson. m{"Feedbackcode": ModelID}). One (&f)return&F, Nil}func (M*feedbackmodel) Insertmodel (model *Feedbackmodel) Error {//part of the code is omitted hereF: = session. DB (Confinstance.dbname). C"Feedback") Err=F.insert (model)returnErr}

Here you need to mention a little bit about mongodb knowledge. In MongoDB, the library is also a library, but the table is not called a table, called collection. Keywords are not translated. The translation is too bad to see the meaning clearly. Each record is not called a record, which is called document. The size of a document cannot exceed 2M.

Looking in MongoDB is like this:

db. Feedback. Find({"Feedbackcode": "1"})/ /Lookup condition is {"Feedbackcode": "1"})//Find condition is

If you don't write anything in Find, it's all unconditional search. The insertion is like this:

db. Feedback. Insert({"Feedbackcode": "2"})

Golang MgO Of course in the specific operation of the database and MongoDB itself is not too much, except that this is the go syntax encapsulation.

collection : = session. DB(confinstance. DBName). C("Feedback")

So we get a collection. The actions such as find, insert, modify, etc. are performed on collection. So, the search is like this:

collection. Find(conditions). All(&feedbackmodellist)

The found list is stored in a pre-declared feedback model list. Find a way to do this:

collection. Find(bson. M{"Feedbackcode": modelid}). One(&F)

Insert:

collection. Insert(model)

Insert, this model needs to be a pointer type, namely: var model *FeedbackModel .

Here you can concatenate the entire feedback from the request to the return process.

All in tandem.

At the entire app entrance. The requested path and the specific controller handler are bound together. After each request comes up, if the path and the path to the binding are good. will be processed in a binding function that is sent to the controller.

This controller method, which handles HTTP requests, sends the JSON string sent by the HTTP request to the Model module for processing. The Model module converts the JSON string to a model instance. The model is a rich modelthat can call its function to insert data from the model itself into the MONGO database and, of course, to query the data from the database.

Get here

Here you are already familiar with how to develop a simple site with Martini This Golang framework, well, is actually a rest Api. Using the render frame mentioned in this article, you can easily convert the model data and display it in the HTML template. And you're already familiar with the MongoDB database. A very easy-to-use database. Whether you are developing a REST API or developing an HTML site. Everything you need to store can be stored in a MongoDB database. Here you have been able to continue the development of the following features smoothly.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.