Controller

Controller is the layer of handling request.

Organization

.
`-- app
    `-- controller
        `-- root.go`

Basics

You can use kocha command line tool to create a new controller as follows:

kocha g controller NAME

Where "NAME" is the controller name.

NOTE: The following command is same as above because g is aliased to generate subcommand:

kocha generate controller NAME

The above command also generates a template file into app/view/ directory and adds route into config/routes.go automatically.

Render

Kocha provides some renderer for various purpose.

Render (godoc)

Render a template that collect from a template directory in boot time (Usually, app/view).

func (r *Root) GET(c *kocha.Context) error {
    return c.Render(nil)
}

By default, template type is text/html. It responds app/view/root.html.tmpl. (Where root in root.html.tmpl is the Controller name mapped to snake case)
If ContentType isn't specified, render the file type specific template that it detects by ContentType.

e.g.

func (r *Root) GET(c *kocha.Context) error {
    c.Response.ContentType = "application/json"
    return c.Render(nil)
}

The above responds app/view/root.json template.

Also Render can be passed data to Template.Execute:

func (r *Root) GET(c *kocha.Context) error {
    return c.Render(map[string]interface{}{
        "name": "alice",
    })
}

RenderJSON (godoc)

Render context as JSON. See json.Marshal for encode details.

func (r *Root) GET(c *kocha.Context) error {
    return c.RenderJSON(map[string]interface{}{
        "name": "alice",
        "id": 1,
    })
}

If you want to render your own JSON format, please use Render with ContentType specified to application/json.

RenderXML (godoc)

Render context as XML. See xml.Marshal for encode details.

import "encoding/xml"

func (r *Root) GET(c *kocha.Context) error {
    return c.RenderXML(struct {
        XMLName xml.Name `xml:"person"`
        Id      int      `xml:"id"`
        Name    string   `xml:"name"`
    }{
        Id:   1,
        Name: "Alice",
    })
}

If you want to render your own XML format, please use Render with ContentType specified to application/xml.

RenderText (godoc)

Render plain text.

func (r *Root) GET(c *kocha.Context) error {
    return c.RenderText("something")
}

If you want to templating text, please use Render with ContentType specified to text/plain.

RenderError (godoc)

Render template (or returns status text) with status code.

func (r *Root) GET(c *kocha.Context) error {
    return c.RenderError(http.StatusBadRequest, nil, nil)
}

Also you can pass an error to the first argument of RenderError.
The passed error will be logging by c.App.Logger.Error.

func (r *Root) GET(c *kocha.Context) error {
    if err := DoSomething(); err != nil {
        return c.RenderError(500, err, nil)
    }
}

See (RenderError) for more details.

SendFile (godoc)

Render a static file that gets from the static file directory (Usually, public).
Or gets from binary included resources (See True All-in-One binary).

func (r *Root) GET(c *kocha.Context) error {
    return c.SendFile("/path/to/file")
}

If passed path is absolute, render the content read from the path as it is.
If passed path is relative, First, try to get the content from included resources and returns it if success. Otherwise, The static directory path adds to the prefix of the path and then will render the content read from the path that.

For example, an absolute path:

c.SendFile("/srv/favicon.ico")

The above responds /srv/favicon.ico.

A relative path:

c.SendFile("favicon.ico")

The above responds public/favicon.ico.

Redirect (godoc)

A shorthand for redirect of both Http.StatusMovedPermanently (301) and http.StatusFound (302).

Using Redirect renderer:

func (r *Root) GET(c *kocha.Context) error {
    // MovedPermanently if second argument is true.
    return c.Redirect("/path/to/redirect", false)
}

is same as below:

func (r *Root) GET(c *kocha.Context) error {
    c.Response.StatusCode = http.StatusFound
    c.Response.Header().Set("Location", "/path/to/redirect")
    return c.RenderText("")
}

Parameter

Controller can take the routing parameters.

If route defined as following in config/routes.go:

Path: "/:id"

Controller can take the parameter by Context.Params.

func (r *Root) GET(c *kocha.Context) error {
    id := c.Params.Get("id")
    return c.Render(map[string]interface{}{
        "id": id,
    })
}

The parameter that taken out is a string type. If you want other types, you can convert to other types using such as strconv.

Of course, it can take the multiple parameters:

Path: "/:id/:name"
func (r *Root) GET(c *kocha.Context) error {
    return c.Render(map[string]interface{}{
        "id": c.Params.Get("id"),
        "name": c.Params.Get("name"),
    })
}

For more details of definition of route parameters, see Route parameter.

Built-in controller