If you have used nginx, you may know that nginx supports hot update, which means you can update your nginx without stopping and restarting it. It serves old connections with old version, and accepts new connections with new version. Notice that hot compiling is different from hot update, where hot compiling is monitoring your source files and recompile them when the content changes, it requires stop and restart your applications, `bee start` is a tool for hot compiling.
##Is hot update necessary?
## Is hot update necessary?
Some people says that hot update is not as useful as its cool name. In my opinion, this is absolutely necessary because zero-down server is our goal for our services. Even though sometimes some errors or hardware problems may occur, but it belongs to design of high availability, don't mix them up. Service update is a known issue, so we need to fix this problem.
##How Beego support hot update?
## How Beego support hot update?
The basic principle of hot update: main process fork a process, and child process execute corresponding programs. So what happens? We know that after forked a process, main process will have all handles, data and stack, etc, but all handles are saved in `CloseOnExec`, so all copied handles will be closed when you execute it unless you clarify this, and we need child process to reuse the handle of `net.Listener`. Once a process calls exec functions, it is "dead", system replaces it with new code. The only thing it left is the process ID, which is the same number but it is a new program after executed.
Therefore, the first thing we need to do is that let child process fork main process and through `os.StartProcess` to append files that contains handle that is going to be inherited.
@ -15,7 +20,8 @@ The final step is that we want to serve old connections with old version of appl
Above are three problems that we need to solve, you can see my code logic for specific implementation.
##Show time
## Show time
1. Write code in your Get method:
@ -26,15 +32,15 @@ Above are three problems that we need to solve, you can see my code logic for sp
}
2. Open two terminals:
One execute: ` ps -ef|grep <application name>`
Another one execute:`curl "http://127.0.0.1:8080/?sleep=20"`
Another one execute:`curl "http://127.0.0.1:8080/?sleep=20"`
3. Hot update
`kill -HUP <PID>`
4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.
4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.
Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also.
- Before anything you do, you have to check that you installed Go in your computer, see more detail about Go installation in my book: [Chapter 1](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/01.1.md)
- Use `go get ` to install Beego:
- Use `go get ` to install Beego:
go get github.com/astaxie/beego
- Install bee tools for fast-develop Beego applications:
go get github.com/astaxie/bee
- Install bee tools for fast-develop Beego applications:
Good job, you're ready to Beego with powerful bee tools!
go get github.com/astaxie/bee
Good job, you're ready to Beego with powerful bee tools!

@ -22,4 +23,4 @@ Beego has following dependency packages:
- To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday)
Hey, you say you've never heard about Beego and don't know how to use it? Don't worry, after you read this section, you will know a lot about Beego. Before you start reading, make sure you installed Beego in your computer, if not, check this tutorial: [Installation](Install.md)
**Navigation**
@ -23,11 +24,13 @@ Hey, you say you've never heard about Beego and don't know how to use it? Don't
@ -54,18 +57,25 @@ Open address [http://127.0.0.1:8080](http://127.0.0.1:8080) in your browser and
What happened in behind above example?
1. We import package `github.com/astaxie/beego`. As we know that Go initialize packages and runs init() function in every package(more detail [here](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/02.3.md#main-function-and-init-function)), so Beego initializes the BeeApp application at this time.
1. We import package `github.com/astaxie/beego`. As we know that Go initialize packages and runs init() function in every package ([more details](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/02.3.md#main-function-and-init-function)), so Beego initializes the BeeApp application at this time.
2. Define controller. We define a struct called `MainController` with a anonymous field `beego.Controller`, so the `MainController` has all methods that `beego.Controller` has.
3. Define RESTful methods. Once we use anonymous combination, `MainController` has already had `Get`, `Post`, `Delete`, `Put` and other methods, these methods will be called when user sends corresponding request, like `Post` method for requests that are using POST method. Therefore, after we overloaded `Get` method in `MainController`, all GET requests will use `Get` method in `MainController` instead of in `beego.Controller`.
4. Define main function. All applications in Go use main function as entry point as C does.
5. Register routers, it tells Beego which controller is responsibility for specific requests. Here we register `/` for `MainController`, so all requests in `/` will be handed to `MainController`. Be aware that the first argument is the path and the second one is pointer of controller that you want to register.
6. Run application in port 8080 as default, press `Ctrl+c` to exit.
## New project
Get into your $GOPATH, then use following command to setup Beego project:
bee create hello
It generates folders and files for your project, directory structure as follows:
.
@ -82,7 +92,9 @@ It generates folders and files for your project, directory structure as follows:
└── views
└── index.tpl
## Development mode
Beego uses development mode as default, you can use following code to change mode in your application:
beego.RunMode = "pro"
@ -95,7 +107,7 @@ No differences between two ways.
In development mode, you have following effects:
- If you don't have directory `views`, it prints following error prompt:
- If you don't have directory `views`, it prints following error prompt:
2013/04/13 19:36:17 [W] [stat views: no such file or directory]
@ -104,7 +116,9 @@ In development mode, you have following effects:

## Router
The main function of router is to connect request URL and handler. Beego wrapped `Controller`, so it connects request URL and `ControllerInterface`. The `ControllerInterface` has following methods:
type ControllerInterface interface {
@ -132,39 +146,41 @@ Users can use following ways to register route rules:
For more convenient configure route rules, Beego references the idea from sinatra, so it supports more kinds of route rules as follows:
After you setting static directory, when users visit `/images/login/login.png`,Beego accesses `images/login/login.png` in related to your application directory. One more example, if users visit `/static/img/logo.png`, Beego accesses file `public/img/logo.png`.
##Filter and middleware
## Filter and middleware
Beego supports customized filter and middleware, such as security verification, force redirect, etc.
Here is an example of verify user name of all requests, check if it's admin.
var FilterUser = func(w http.ResponseWriter, r *http.Request) {
if r.URL.User == nil || r.URL.User.Username() != "admin" {
http.Error(w, "", http.StatusUnauthorized)
}
if r.URL.User == nil || r.URL.User.Username() != "admin" {
beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) {
dosomething()
dosomething()
})
Filter by prefix is also available:
beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) {
dosomething()
dosomething()
})
##Controller
## Controller
Use `beego.controller` as anonymous in your controller struct to implement the interface in Beego:
type xxxController struct {
beego.Controller
beego.Controller
}
`beego.Controller` implemented`beego.ControllerInterface`, `beego.ControllerInterface` defined following methods:
@ -214,15 +234,15 @@ Use `beego.controller` as anonymous in your controller struct to implement the i
- Init(ct `*`Context, cn string)
Initialize context, controller's name, template's name, and container of template arguments
- Prepare()
This is for expend usages, it executes before all the following methods. Users can overload this method for verification for example.
- Get()
This method executes when client sends request as GET method, 403 as default status code. Users overload this method for customized handle process of GET method.
- Post()
This method executes when client sends request as POST method, 403 as default status code. Users overload this method for customized handle process of POST method.
@ -258,7 +278,7 @@ Use `beego.controller` as anonymous in your controller struct to implement the i
Overload all methods for all customized logic processes, let's see an example:
type AddController struct {
beego.Controller
beego.Controller
}
func (this *AddController) Prepare() {
@ -266,54 +286,64 @@ Overload all methods for all customized logic processes, let's see an example:
}
func (this *AddController) Get() {
this.Data["content"] ="value"
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
this.Data["content"] ="value"
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
}
func (this *AddController) Post() {
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp models.PkgEntity
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
models.InsertPkg(pp)
pk = models.GetCruPkg(pkgname)
}
var at models.Article
at.Pkgid = pk.Id
at.Content = content
models.InsertArticle(at)
this.Ctx.Redirect(302, "/admin/index")
}
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp models.PkgEntity
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
models.InsertPkg(pp)
pk = models.GetCruPkg(pkgname)
}
var at models.Article
at.Pkgid = pk.Id
at.Content = content
models.InsertArticle(at)
this.Ctx.Redirect(302, "/admin/index")
}
## Template
### Template directory
##Template
###Template directory
Beego uses `views` as the default directory for template files, parses and caches them as needed(cache is not enable in develop mode), but you can **change**(because only one directory can be used for template files) its directory using following code:
beego.ViewsPath = "/myviewpath"
###Auto-render
### Auto-render
You don't need to call render function manually, Beego calls it automatically after corresponding methods executed. If your application is somehow doesn't need templates, you can disable this feature either in code of `main.go` or configuration file.
To disable auto-render in configuration file:
autorender = false
To disable auto-render in `main.go`(before you call `beego.Run()` to run the application):
beego.AutoRender = false
###Template data
### Template data
You can use `this.Data` in controller methods to access the data in templates. Suppose you want to get content of `{{.Content}}`, you can use following code to do this:
this.Data["Context"] = "value"
###Template name
Beego uses built-in template engine of Go, so there is no different in syntax. As for how to write template file, please visit [Template tutorial](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/07.4.md)。
### Template name
Beego uses built-in template engine of Go, so there is no different in syntax. As for how to write template file, please visit [Template tutorial](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/07.4.md).
Beego parses template files in `viewpath` and render it after you set the name of the template file in controller methods. For example, Beego finds the file `add.tpl` in directory `admin` in following code:
@ -329,16 +359,18 @@ If you enabled auto-render and you don't tell Beego which template file you are
Which is `<corresponding controller name>/<request method name>.<template extension>`. For example, your controller name is `AddController` and the request method is POST, and the default file extension is `tpl`, so Beego will try to find file `/<viewpath>/AddController/POST.tpl`.
###Layout design
### Layout design
Beego supports layout design, which means if you are working on an administration application, and some part of its user interface is exactly same all the time, then you can make this part as a layout.
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
You have to set following variable in order to make Beego possible to insert your dynamic content:
{{.LayoutContent}}
Beego parses template file and assign content to `LayoutContent`, and render them together.
Right now, Beego caches all template files, so you can use following way to implement another kind of layout:
@ -347,12 +379,14 @@ Right now, Beego caches all template files, so you can use following way to impl
Handle logic
{{template "footer.html"}}
###Template function
### Template function
Beego supports customized template functions that are registered before you call `beego.Run()`.
func hello(in string)(out string){
out = in + "world"
return
out = in + "world"
return
}
beego.AddFuncMap("hi",hello)
@ -363,35 +397,45 @@ Then you can use this function in your template files:
There are some built-in template functions:
* markdown
* markdown
This function converts markdown content to HTML format, use {{markdown .Content}} in template files.
* dateformat
* dateformat
This function converts time to formatted string, use {{dateformat .Time "2006-01-02T15:04:05Z07:00"}} in template files.
* date
* date
This function implements date function like in PHP, use formatted string to get corresponding time, use {{date .T "Y-m-d H:i:s"}} in template files.
* compare
* compare
This functions compares two objects, returns true if they are same, false otherwise, use {{compare .A .B}} in template files.
* substr
* substr
This function cuts out string from another string by index, it supports UTF-8 characters, use {{substr .Str 0 30}} in template files.
* html2str
* html2str
This function escapes HTML to raw string, use {{html2str .Htmlinfo}} in template files.
* str2html
* str2html
This function outputs string in HTML format without escaping, use {{str2html .Strhtml}} in template files.
* htmlquote
* htmlquote
This functions implements basic HTML escape, use {{htmlquote .quote}} in template files.
* htmlunquote
* htmlunquote
This functions implements basic invert-escape of HTML, use {{htmlunquote .unquote}} in template files.
##Handle request
## Handle request
We always need to get data from users, including methods like GET, POST, etc. Beego parses these data automatically, and you can access them by following code:
- GetString(key string) string
@ -413,18 +457,20 @@ If you need other types that are not included above, like you need int64 instead
func (this *MainController) Post() {
id := this.Input().Get("id")
intid, err := strconv.Atoi(id)
}
}
To use `this.Ctx.Request` for more information about request, and object properties and method please read [Request](http://golang.org/pkg/net/http/#Request)
###File upload
### File upload
It's very easy to upload file through Beego, but don't forget to add `enctype="multipart/form-data"` in your form, otherwise the browser will not upload anything.
Files will be saved in memory, if the size is greater than cache memory, the rest part will be saved as temporary file. The default cache memory is 64 MB, and you can using following ways to change this size.
Files will be saved in memory, if the size is greater than cache memory, the rest part will be saved as temporary file. The default cache memory is 64 MB, and you can use following ways to change this size.
In code:
beego.MaxMemory = 1<<22
beego.MaxMemory = 1<<22
Inconfigurationfile:
@ -435,56 +481,60 @@ Beego provides two convenient functions to upload files:
Beego is a lightweight, open source, non-blocking and scalable web framework for the Go programming language. It's like tornado in Python. This web framework has already been using for building web server and tools in SNDA's CDN system. Documentation and downloads available at [http://astaxie.github.com/beego](http://astaxie.github.com/beego)
It has following main features:
@ -19,29 +20,33 @@ The working principles of Beego as follows:
Beego is licensed under the Apache Licence, Version 2.0
People may ask me why I want to build a new web framework rather than use other good ones. I know there are many excellent web frameworks on the internet and almost all of them are open source, and I have my reasons to do this.
Remember when I was writing the book about how to build web applications with Go, I just wanted to tell people what were my valuable experiences with Go in web development, especially I have been working with PHP and Python for almost ten years. At first, I didn't realize that a small web framework can give great help to web developers when they are learning to build web applications in a new programming language, and it also helps people more by studying its source code. Finally, I decided to write a open source web framework called Beego as supporting materiel for my book.
@ -9,11 +10,11 @@ I used to use CI in PHP and tornado in Python, there are both lightweight, so th
2. Learn more about languages by studying their source code, it's not hard to read and understand them because they are both lightweight frameworks.
3. It's quite easy to make secondary development of these frameworks for specific purposes.
Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in GO.
Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in Go.
Then I started to design logic execution of Beego. Because Go and Python have somewhat similar, I referenced some ideas from tornado to design Beego. As you can see, there is no different between Beego and tornado in RESTful processing; they both use GET, POST or some other methods to implement RESTful. I took some ideas from [https://github.com/drone/routes](https://github.com/drone/routes) at the beginning of designing routes. It uses regular expression in route rules processing, which is an excellent idea that to make up for the default Mux router function in Go. However, I have to design my own interface in order to implement RESTful and use inherited ideas in Python.
The controller is the most important part of whole MVC model, and Beego uses the interface and ideas I said above for the controller. Although I haven't decided to have to design the model part, everyone is welcome to implement data management by referencing Beedb, my another open source project. I simply adopt Go built-in template engine for the view part, but add more commonly used functions as template functions. This is how a simple web framework looks like, but I'll keep working on form processing, session handling, log recording, configuration, automated operation, etc, to build a simple but complete web framework.
- [Introduction](README.md)
- [Installation](Install.md)
- [Installation](Install.md)
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.