diff --git a/docs/en/API.md b/docs/en/API.md deleted file mode 100644 index 1409d882..00000000 --- a/docs/en/API.md +++ /dev/null @@ -1,102 +0,0 @@ -# Getting start with API application development -Go is very good for developing API applications which I think is the biggest strength compare to other dynamic languages. Beego provides powerful and quick setup tool for developing API applications, which gives you more focus on business logic. - - -## Quick setup -bee can setup a API application very quick by executing commands under any `$GOPATH/src`. - -`bee api beeapi` - -## Application directory structure - - ``` -├── conf -│ └── app.conf -├── controllers -│ └── default.go -├── models -│ └── object.go -└── main.go -``` - -## Source code explanation - -- app.conf has following configuration options for your API applications: - - - autorender = false // Disable auto-render since API applications don't need. - - copyrequestbody = true // RESTFul applications sends raw body instead of form, so we need to read body specifically. - -- main.go is for registering routers of RESTFul. - - beego.RESTRouter("/object", &controllers.ObejctController{}) - -Match rules as follows: - - - - - - - - - - - - - - - - - - - - -
URL HTTP Verb Functionality
/object POST Creating Objects
/object/objectId GET Retrieving Objects
/object/objectId PUT Updating Objects
/object GET Queries
/object/objectId DELETE Deleting Objects
- -- ObejctController implemented corresponding methods: - - type ObejctController struct { - beego.Controller - } - - func (this *ObejctController) Post(){ - - } - - func (this *ObejctController) Get(){ - - } - - func (this *ObejctController) Put(){ - - } - - func (this *ObejctController) Delete(){ - - } - -- models implemented corresponding object operation for adding, deleting, updating and getting. - -## Test - -- Add a new object: - - curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object - - Returns a corresponding objectID:astaxie1373349756660423900 - -- Query a object: - - `curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900` - -- Query all objects: - - `curl -X GET http://127.0.0.1:8080/object` - -- Update a object: - - `curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900` - -- Delete a object: - - `curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900` diff --git a/docs/en/HotUpdate.md b/docs/en/HotUpdate.md deleted file mode 100644 index 91bd6a49..00000000 --- a/docs/en/HotUpdate.md +++ /dev/null @@ -1,46 +0,0 @@ -## What is hot update? - -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? - -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? - -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. - -The second step is that we hope child process can start listening from same handle, so we can use `net.FileListener` to achieve this goal. Here we also need FD of this file, so we need to add a environment variable to set this FD before we start child process. - -The final step is that we want to serve old connections with old version of application, and serve new connections with new version. So how can we know if there is any old connections? To do this, we have to record all connections, then we are able to know. Another problem is that how to let new application to accept connection? Because two versions of applications are listening to same port, they get connection request randomly, so we just close old accept function, and it will get error in `l.Accept`. - -Above are three problems that we need to solve, you can see my code logic for specific implementation. - - -## Show time - -1. Write code in your Get method: - - func (this *MainController) Get() { - a, _ := this.GetInt("sleep") - time.Sleep(time.Duration(a) * time.Second) - this.Ctx.WriteString("ospid:" + strconv.Itoa(os.Getpid())) - } - -2. Open two terminals: - - One execute: ` ps -ef|grep ` - - Another one execute: `curl "http://127.0.0.1:8080/?sleep=20"` - -3. Hot update - - `kill -HUP ` - -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. diff --git a/docs/en/Install.md b/docs/en/Install.md deleted file mode 100644 index f51db397..00000000 --- a/docs/en/Install.md +++ /dev/null @@ -1,26 +0,0 @@ -# Installation - -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: - - go get github.com/astaxie/beego - -- Install bee tools for fast-develop Beego applications: - - go get github.com/astaxie/bee - -Good job, you're ready to Beego with powerful bee tools! - -![](images/bee.png) - -Beego has following dependency packages: - -- Session module: [github.com/astaxie/beego/session](https://github.com/astaxie/beego/session) -- To support redis engine: [github.com/garyburd/redigo/redis](https://github.com/garyburd/redigo/redis) -- To support mysql engine: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) -- To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday) - -- [Introduction](README.md) -- [Quick start](Quickstart.md) diff --git a/docs/en/Quickstart.md b/docs/en/Quickstart.md deleted file mode 100644 index 5e821c1f..00000000 --- a/docs/en/Quickstart.md +++ /dev/null @@ -1,1128 +0,0 @@ -# Quick start - -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** - -- [Hello world](#hello-world) -- [New project](#new-project) -- [Development mode](#development-mode) -- [Router](#router) -- [Static files](#static-files) -- [Filter and middleware](#filter-and-middleware) -- [Controller](#controller) -- [Template](#template) -- [Handle request](#handle-request) -- [Redirect and error](#redirect-and-error) -- [Handle response](#handle-response) -- [Sessions](#sessions) -- [Cache](#cache) -- [Safe map](#safe-map) -- [Log](#log) -- [Configuration](#configuration) -- [Beego arguments](#beego-arguments) -- [Integrated third-party applications](#integrated-third-party-applications) -- [Deployment](#deployment) - - -## Hello world - -This is an example of "Hello world" in Beego: - - package main - - import ( - "github.com/astaxie/beego" - ) - - type MainController struct { - beego.Controller - } - - func (this *MainController) Get() { - this.Ctx.WriteString("hello world") - } - - func main() { - beego.Router("/", &MainController{}) - beego.Run() - } - -Save file as "hello.go", build and run it: - - $ go build main.go - $ ./hello - -Open address [http://127.0.0.1:8080](http://127.0.0.1:8080) in your browser and you will see "hello world". - -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 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 new hello - -It generates folders and files for your project, directory structure as follows: - - . - ├── conf - │ └── app.conf - ├── controllers - │ └── default.go - ├── main.go - ├── models - ├── static - │ ├── css - │ ├── img - │ └── js - └── views - └── index.tpl - - -## Development mode - -Beego uses development mode as default, you can use following code to change mode in your application: - - beego.RunMode = "prod" - -Or use configuration file in `conf/app.conf`, and input following content: - - runmode = prod - -No differences between two ways. - -In development mode, you have following effects: - -- 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] - -- It doesn't cache template and reload every time. -- If panic occurs in your server, it prints information like following screen shot: - -![](images/dev.png) - - -## 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 { - Init(ct *Context, cn string) - Prepare() - Get() - Post() - Delete() - Put() - Head() - Patch() - Options() - Finish() - Render() error - } - -`beego.Controller` implemented all of them, so you just use this struct as anonymous field in your controller struct. Of course you have to overload corresponding methods for more specific usages. - -Users can use following ways to register route rules: - - beego.Router("/", &controllers.MainController{}) - beego.Router("/admin", &admin.UserController{}) - beego.Router("/admin/index", &admin.ArticleController{}) - beego.Router("/admin/addpkg", &admin.AddController{}) - -For more convenient configure route rules, Beego references the idea from sinatra, so it supports more kinds of route rules as follows: - -- beego.Router("/api/:id([0-9]+)", &controllers.RController{}) - - Customized regular expression match // match /api/123 :id= 123 - -- beego.Router("/news/:all", &controllers.RController{}) - - Match rest of all // match /news/path/to/123.html :all= path/to/123.html - -- beego.Router("/user/:username([\w]+)", &controllers.RController{}) - - Regular expression // match /user/astaxie :username = astaxie - -- beego.Router("/download/`*`.`*`", &controllers.RController{}) - - Wildcard character // match /download/file/api.xml :path= file/api :ext=xml - -- beego.Router("/download/ceshi/`*`", &controllers.RController{}) - - wildcard character match rest of all // match /download/ceshi/file/api.json :splat=file/api.json - -- beego.Router("/:id:int", &controllers.RController{}) - - Match type int // match :id is int type, Beego uses regular expression ([0-9]+) automatically - -- beego.Router("/:hi:string", &controllers.RController{}) - - Match type string // match :hi is string type, Beego uses regular expression ([\w]+) automatically - - -## Static files - -Go provides `http.ServeFile` for static files, Beego wrapped this function and use following way to register static file folder: - - beego.SetStaticPath("/static","public") - -- The first argument is the path of your URL. -- The second argument is the directory in your application path. - -Beego supports multiple static file directories as follows: - - beego.SetStaticPath("/images","images") - beego.SetStaticPath("/css","css") - beego.SetStaticPath("/js","js") - -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 - -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) - } - } - - beego.Filter(FilterUser) - -You can also filter by arguments: - - beego.Router("/:id([0-9]+)", &admin.EditController{}) - beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) { - dosomething() - }) - -Filter by prefix is also available: - - beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { - dosomething() - }) - - -## Controller - -Use `beego.controller` as anonymous in your controller struct to implement the interface in Beego: - - type xxxController struct { - beego.Controller - } - -`beego.Controller` implemented`beego.ControllerInterface`, `beego.ControllerInterface` defined following methods: - -- 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. - -- Delete() - - This method executes when client sends request as DELETE method, 403 as default status code. Users overload this method for customized handle process of DELETE method. - -- Put() - - This method executes when client sends request as PUT method, 403 as default status code. Users overload this method for customized handle process of PUT method. - -- Head() - - This method executes when client sends request as HEAD method, 403 as default status code. Users overload this method for customized handle process of HEAD method. - -- Patch() - - This method executes when client sends request as PATCH method, 403 as default status code. Users overload this method for customized handle process of PATCH method. - -- Options() - - This method executes when client sends request as OPTIONS method, 403 as default status code. Users overload this method for customized handle process of OPTIONS method. - -- Finish() - - This method executes after corresponding method finished, empty as default. User overload this method for more usages like close database, clean data, etc. - -- Render() error - - This method is for rendering template, it executes automatically when you set beego.AutoRender to true. - -Overload all methods for all customized logic processes, let's see an example: - - type AddController struct { - beego.Controller - } - - func (this *AddController) Prepare() { - - } - - func (this *AddController) Get() { - 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") - } - - -## 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 - -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 - -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["Content"] = "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). - -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: - - this.TplNames = "admin/add.tpl" - -Beego supports two kinds of extensions for template files, which are `tpl` and `html`, if you want to use other extensions, you have to use following code to let Beego know: - - beego.AddTemplateExt("") - -If you enabled auto-render and you don't tell Beego which template file you are going to use in controller methods, Beego uses following format to find the template file if it exists: - - c.TplNames = c.ChildName + "/" + c.Ctx.Request.Method + "." + c.TplExt - -Which is `/.