Quickly building a Web application instance tutorial with Golang (Go language)

Source: Internet
Author: User
Tags define function manual json prepare require stmt

1.Abstract

There are a lot of difficulties in learning web development, so you write an article that looks like a review class. As the roadmap from the Web Development element index to introduce Golang development of the learning process and example code.

Much of the description is used in code to describe how the usage method does not do too much. Finally you can easily copy the code to achieve their own needs.

This article adapts to the object:

Someone with a certain experience in web development
People who can use Ajax flexibly (at least know how to detach before and after)
Golang Web Development has some understanding, at least skim over some golang web development books

After reading this article you will reap:

Some tips for Golang web development
Some practical APIs for Golang Web development

In this article, the explanations are written into the code comments to explain as much detail as possible in the description.

2.golang Web Development Check list

Skip over parts: Basic Process Control, OOP and other basic grammar knowledge.

3. Router

Routers are the soul of the entire site, if the route is not good URL will be very disgusting. So this part is designed to be the first one to say.

There are two types of routing: manual routing in order to schedule fixed functions through Tul, another point is the acquisition of resources, through the analysis of the URL to mimic the way of static pages to obtain resources (like get)

Automatic routing, which is mainly implemented using OOP command mode. All features use post, unified access, easy access management, security management, cross domain management. But such a powerful function is to give the framework to do it. This is not for beginners to do the reference.

3.1 Manual Routing

Package Main
Import (
"Log"
"Net/http"
)
Func Main () {
Routerbinding ()///Routing binding functions
ERR: = http. Listenandserve (": 9090", nil)//set the listening port
If Err!= nil {
Log. Fatal ("Listenandserve:", err)
}
}

Bind a route before Httpserver runs
3.2 Binding for manual routing
3.2.1 Static File

http. Handle ("/pages/", http. Stripprefix ("/pages/", http. Fileserver (http. Dir ("./pages")))

3.2.2 Fixed function and resource acquisition

They're all the same.

http. Handlefunc ("/images/", fileupload.downloadpictureaction)

4. Page load

4.1 Pure Static page (HTML)

Just give it to the route. Automatically access that folder. However, the production environment is still a CDN, if its own server more. You can nginx the reverse proxy.

The main benefits of separation before and after, can be on the CDN is the number of communications. But it's OK to improve by optimizing.

4.2 Template Page Loading

Commonpage, err: = template. Parsefiles ("Pages/common/head.gtpl",//Load template
"Pages/common/navbar.gtpl", "PAGES/COMMON/TAIL.GTPL")
If Err!= nil {
Panic (err. Error ())
}
Navargs: = map[string]string{"Home": "Home", "User": "Yupengfei"}//complex parameters begin to plug in
Knowledgepage, err: = template. Parsefiles ("Pages/knowledge/knowledge.gtpl")
Knowledgeargs: = map[string]interface{}{"Head": "This is a test title",
"Author": "Kun.wang", "Publishdatetime": "2014-09-14",
"Content": template. HTML ("<p style=\" text-indent:2em\) > Why should you be semantic? </p> ")}//is not bad, just do string analysis will affect engineering efficiency
Commonpage.executetemplate (W, "header", nil)//render Start
Commonpage.executetemplate (W, "NavBar", Navargs)
Knowledgepage.executetemplate (W, "knowledge", Knowledgeargs)
Commonpage.executetemplate (W, "tail", nil)

Provides only critical code.

The other is very good, is the page rendering using the server is not a bit too extravagant.
string array as input parameter error is more difficult
Summary: Although reducing the number of communications, but there is no way to the Cdn egg pain, in addition, the template of the mapping egg pain.

5. Presentation Layer Script


The presentation layer script is harder and less studious. But once it's done, the reusability of the code can be considerably improved.

In general, JS development efficiency is very high flexibility, and the use of the client's CPU performance is good, free resources, more people learn, good recruitment.

5.1 Require.js
5.1.1 Loading

<script data-main= "/reqmod/login_main" language= "JavaScript" defer async= "true" src= "Js/r.js" ></script>

The entire page is left with such a loading script entry (preferably only one JS file per page)

Benefits

JS is deferred loading. There will be no Web page card death.
Maximizes the use of caching. (HTTP 304)
A Web page with only one JS
DOM event bindings without writing the JS binding on the HTML control

Harm

Learning is more difficult
Web site updates always have browsers that are not updated by the cache. Cause errors (so some cases customers themselves know how many times to refresh, has become a user's habit)

Parameter explanation

' Data-main ' business logic entry, loading the current string. js this file
' Language ' does not explain
' defer async ' literal meaning
' src ' r.js is the meaning of require.js. The code can be got everywhere.

5.1.2 Page Business

Load dependent files

Require.baseurl = "/"
Require.config ({
BASEURL:REQUIRE.BASEURL,
Paths: {
"jquery": "Js/jquery-1.10.2.min",
"Domready": "Reqmod/domready",
"PM": "Reqmod/pmodal",
"Cookie": "Reqmod/cookie",
"User": "Reqmod/user",
"Bootstrap": "Reqmod/bootstrap.min",
"NAV": "Reqmod/nav"
},
Shim: {
' Bootstrap ': {
Deps: [' jquery ']
}
}
});
Direct copy is all done.

Execute page Business

The most that you do in execution is the DOM and the event bindings. Load a variety of JS Library direct Reference.

The code is beautiful, development efficiency, execution efficiency is very good.

require ([' Nav ', ' domready ', ' jquery ', ' user ', ' pm '], function (Nav,doc, $, user,pm) {
The first ' array ' parameter of this function is the selected dependent module. 1. Website absolute path. 2. Select the content of export when using load dependent module
The order of the arrays is the same as the function order, and if there are two modules that rely on such as the jquery plugin, write the last variable and use the ' $ '
Doc (function () {//Domready
Pm.load ()//loading various plugins HTML templates and all OK
$ (' #btn_login ') [0].onclick = function () {User.login ();} Button Event Binding
});
});

Page model

define ([' jquery ', ' Reqmod/cookie ', ' user ', ' Bootstrap '],function ($,cookie,user) {
The parameter content of the Define function is require the same.
The modules that are dependent here have path configuration in the module that calls this module. Otherwise will die very miserably, when the error will not say what is missing what place wrong.
var nav_load = function () {//Note the way functions are defined copy on line
$.get ('/nav.html ', function (result) {
var newNode = document.createelement ("div");
newnode.innerhtml = result;
$ (' body ') [0].insertbefore (newnode,$ (' body ') [0].firstchild);
Document.body.innerHTML = result + Document.body.innerHTML;
$ (' #btn_login ') [0].onclick = function () {User.login ();}
$ (' #btn_reg ') [0].onclick = function () {window.location= '/register.html '}
$.post ('/login_check ', {},function (data) {
if (data==0) {
Form_login.style.display= ""
}
else{
Form_userinfo.style.display= ""
}
})
});
}
return {//here is similar to the mini route. Very flexible, very convenient
Load:nav_load
};
});

5.2 JQuery

The JQ function is basically the same as long as the Require.js is quoted.

If you need to be able to study on the W3school.

6. Business Layer

Post analysis

Func xxxaction (w http. Responsewriter, R *http. Request) {
R.parseform ()///have this to get the parameters
r.form["Email"]//Get email parameter (String)
Write the next business.
}

Resource Entry function resource require analysis (URL analysis fixed notation)

Func Foo (w http. Responsewriter, R *http. Request) {
Queryfile: = Strings. Split (R.url. Path, "/")
Queryresource: = Queryfile[len (Queryfile)-1]/parse file
}
After the string segmentation is complete, it is OK to get the resources according to the requirements.

Enter object directly

Data, err: = Ioutil. ReadAll (R.body)//Direct read form as JSON string
If Err!= nil {
Utility. Simplefeedback (W,, "Failed to read body")
PillarsLog.PillarsLogger.Print ("Failed to read body")
Return
}
K: = "BUSINESS OBJECT"
Err = json. Unmarshal (data, &k)
If Err!= nil {
Utility. Simplefeedback (W, "Pramaters failed!")
PillarsLog.PillarsLogger.Print ("Pramaters failed!")
Return
}
Convenient and quick. When accessing the parameters, it is OK to call the structural body parameters directly.
Note that when Ajax calls a function, you need to make some adjustments to the code as follows:
$.ajax ([Dist],json.stringify ([data]), function () {}, ' json ');/note json

7. Persistence Layer

7.1 Mysql

In fact, no matter what language of the MySQL driver is from pro*c, so will pro*\c after, what all say

Insert/delete/update

stmt, err: = MysqlUtility.DBConn.Prepare ("INSERT into credit (Credit_code, User_code, Credit_rank) VALUES (?,?,?)")
If Err!= nil {
PillarsLog.PillarsLogger.Print (Err. Error ())
return FALSE, Err
}
Defer stmt. Close ()
_, Err = stmt. Exec (Credit. Creditcode, credit. Usercode, credit. Creditrank)
If Err!= nil {
return FALSE, Err
} else {
return true, err
}
It's more convenient.

Query

stmt, err: = MysqlUtility.DBConn.Prepare (' SELECT commodity_code, Commodity_name, description, picture,
Price, storage, count, status,
Insert_datetime, update_datetime from commodity WHERE Commodity_code =? ')
If Err!= nil {
return nil, err
}
Defer stmt. Close ()
result, err: = stmt. Query (Commoditycode)
If Err!= nil {
return nil, err
}
Defer result. Close ()
var commodity utility.commodity
If result. Next () {
Err = result. Scan (& (Commodity.commoditycode), & (Commodity.commodityname), & (commodity. Description),
& (Commodity. Picture), & (commodity. Price), & (commodity. Storage), & (commodity. Count), & (commodity. Status),
& (Commodity. InsertDateTime), & (commodity. Updatedatetime))
If Err!= nil {
PillarsLog.PillarsLogger.Print (Err. Error ())
return nil, err
}
}
Return &commodity, err

7.2 Mongodb

ERR: = MongoUtility.PictureCollection.Find (Bson. m{"Picturecode":* Picturecode}). One (&picture)

The simplest example is given here. Concrete look at the development of MgO document is OK. It's still quite simple.

8. Unit Test Considerations

Test command Go test-v (no more arguments!!! If you do not show the results without-V, the debugging process is not displayed, primarily when you debug the development
File format Xxx_test.go However, it is advisable to change it to xxx_test0.go or change it to something else.
Because of the principle of testing first, there are one or two functions in one Test at development time.
This is equivalent to commenting out other tests
The configuration file to be tested is placed under the test directory. Don't forget.
Mentality, too many mistakes one to come, to have a good mentality.

9.LOG

Note the non-deletion of the log in debugging.

The following API is OK if you do not know where to direct doc search.

Package Utility
Import "Log"
Import "OS"
Import "FMT"
Logger Model min variable.
var Logger *log. Logger
var outfile *os. File
init function if Logger if not inited'll invoke this function
Func init () {
if Logger = = Nil {
PropertyMap: = ReadProperty ("Pic.properties")
LogFileName: = propertymap["LogFile"]
Fmt. Println ("Initial and Open log file", LogFileName)
var err error
outfile, err = os. OpenFile (LogFileName, OS. O_create|os. O_append|os. O_rdwr, 0666)
If Err!= nil {
Panic (err. Error ())
}
Logger = log. New (outfile, "", log.) Ldate|log. Ltime|log. Llongfile)
}
}
Closelogfile function:close Logger invoke file.
Func Closelogfile () {
Outfile.close ()
}

How to use:

Utility. Logger.println ("Log test")

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.