---
# System prepended metadata

title: 'Beego File structure [Api Based App]'

---

# Beego File structure [Api Based App]
![](https://i.imgur.com/yYEL7GW.png)

## Folders & Files
- conf
    - ini file,key value pair
	- holds configuration of application
	- maps with web.Config
	- example : httpport = 8080
- controller
    - controller for a specific namespace
    - inherits web.Controller
    - overrides methods from web.Controller
        - Get, Post.....
- models
    - holds model for each entity
    - has database logic
    - interactions with database
- routers
    - routers are defined
    - namespaces are defined and controllers are assigned
    - has init() functions, which loads at the initial state of running the application
- tests
    - includes http tests/other tests
- other files
    - main.go
    - go mod and sum
    - .gitignore
    - ......
- swagger/swagger.zip
    - depending how the application is started all documentation can be downloaded as `swagger.zip` and extracted to `swagger` folder

## Examples/Details
### conf
conf folder has a file named `app.conf` which is an `ini` file
 
```shell=
appname = beegotodo
httpport = 8080
runmode = dev
autorender = false
copyrequestbody = true
EnableDocs = true
sqlconn = 
```

### controller
controller folder has all the controllers, lets take an example of todocontroller 
 
```go=
//  TodoController operations for Todo
type TodoController struct {
	beego.Controller
}

// URLMapping ...
func (c *TodoController) URLMapping() {
	c.Mapping("Post", c.Post)
	c.Mapping("GetOne", c.GetOne)
	c.Mapping("GetAll", c.GetAll)
	c.Mapping("Put", c.Put)
	c.Mapping("Delete", c.Delete)
}

// Post ...
// @Title Post
// @Description create Todo
// @Param	body		body 	models.Todo	true		"body for Todo content"
// @Success 201 {int} models.Todo
// @Failure 403 body is empty
// @router / [post]
func (c *TodoController) Post() {
	var v models.Todo
	json.Unmarshal(c.Ctx.Input.RequestBody, &v)

	if _, err := models.AddTodo(&v); err == nil {
		c.Ctx.Output.SetStatus(201)
		c.Data["json"] = v
	} else {
		c.Data["json"] = err.Error()
	}

	c.ServeJSON()
}
```
- inherits from web.Controller
- overrides methods
- `web.Controller` implements `ControllerInterface`
- `UrlMapping`, maps each http method to a function
- `Post` handles the post method request
- Controllers communicate with models and serves data from getting it from models or receives data and passes it to models
- Can you see some comments above of the `Post()` method ?
    - these comments are route, method, request, response models,params defination
    - these comments are used to make useful Api documentation
    - also generates global controller route inside `route` package

### models
All models for application goes here, as well as the database CRUD functionalities. lets take an example of todo model
```go=
package models

import (
	"errors"
	"fmt"

	"github.com/beego/beego/v2/client/orm"
)

var (
	todos = []Todo{
		{
			Id:        1,
			Title:     "task 1",
			Completed: false,
		},
		{
			Id:        2,
			Title:     "task 2",
			Completed: false,
		},
		{
			Id:        3,
			Title:     "task 3",
			Completed: true,
		},
	}
)

type Todo struct {
	Id        int64  `orm:"auto"`
	Title     string `orm:"size(128)"`
	Completed bool
}

func init() {
	orm.RegisterModel(new(Todo))
}

// AddTodo insert a new Todo into database and returns
// last inserted Id on success.
func AddTodo(m *Todo) (id int64, err error) {
	todos = append(todos, *m)

	return int64(len(todos)), nil
}
```
- Define models with tagging 
- Register the model
- in this particular example we are using slice of todo, but real life scenario would be crud interactions with database, such as mysql,postgres.... 

### routers
router package is where the namespaces are defined, as well as respected controllers 
```go=
// @APIVersion 1.0.0
// @Title beego Test API
// @Description beego has a very cool tools to autogenerate documents for your API
// @Contact astaxie@gmail.com
// @TermsOfServiceUrl http://beego.me/
// @License Apache 2.0
// @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
package routers

import (
	"github.com/nafeem-evatix/beegotodo/controllers"

	beego "github.com/beego/beego/v2/server/web"
)

func init() {
	ns := beego.NewNamespace("/v1",
		beego.NSNamespace("/todo",
			beego.NSInclude(
				&controllers.TodoController{},
			),
		),
	)

	beego.AddNamespace(ns)
}
```
- notice the comments before `package routers` this also part of the API documentation and is added to the swagger page
- in the init function new namespace is created also todo namespace is defined
- and then added to the beego namespaces
- in simple words this block of code defines API version, creates `todo` name space and mentions which controller should take care of incoming request that starts with `/todo`
- another file `commentsRouter_controllers.go` is generated when running `bee run`
```go=
package routers

import (
	beego "github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context/param"
)

func init() {

    beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"] = append(beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"],
        beego.ControllerComments{
            Method: "Post",
            Router: "/",
            AllowHTTPMethods: []string{"post"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

    beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"] = append(beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"],
        beego.ControllerComments{
            Method: "GetAll",
            Router: "/",
            AllowHTTPMethods: []string{"get"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

    beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"] = append(beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"],
        beego.ControllerComments{
            Method: "GetOne",
            Router: "/:id",
            AllowHTTPMethods: []string{"get"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

    beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"] = append(beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"],
        beego.ControllerComments{
            Method: "Put",
            Router: "/:id",
            AllowHTTPMethods: []string{"put"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

    beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"] = append(beego.GlobalControllerRouter["github.com/nafeem-evatix/beegotodo/controllers:TodoController"],
        beego.ControllerComments{
            Method: "Delete",
            Router: "/:id",
            AllowHTTPMethods: []string{"delete"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

}
```
- this file is generated from the comments defined in the controller package
- this is a map, which uses controller location as key and uses slice of CommentControllers of which each block contains information about the Method to execute for which URL

### tests
all the http tests and other tests should go in this package, a sample test is provided when generating project using `bee` tool.
```go=
package test

import (
	"net/http"
	"net/http/httptest"
	"testing"
	"runtime"
	"path/filepath"
	_ "github.com/nafeem-evatix/beegotodo/routers"

	beego "github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/core/logs"
	. "github.com/smartystreets/goconvey/convey"
)

func init() {
	_, file, _, _ := runtime.Caller(0)
	apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator))))
	beego.TestBeegoInit(apppath)
}

// TestGet is a sample to run an endpoint test
func TestGet(t *testing.T) {
	r, _ := http.NewRequest("GET", "/v1/todo", nil)
	w := httptest.NewRecorder()
	beego.BeeApp.Handlers.ServeHTTP(w, r)

	logs.Info("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())

	Convey("Subject: Test Station Endpoint\n", t, func() {
	        Convey("Status Code Should Be 200", func() {
	                So(w.Code, ShouldEqual, 200)
	        })
	        Convey("The Result Should Not Be Empty", func() {
	                So(w.Body.Len(), ShouldBeGreaterThan, 0)
	        })
	})
}
```
### swagger/swagger.zip
Depending on how the app is ran, docs can be generated, downloaded,extracted and served
### Others
main.go, mod, sum, gitignore files....

## Advantages 
- Follows `MVC` pattern
- Since generated by tool less likely to have errors
- The `bee` tool works great with this structure
- Less work, generating models, controller usually is based on this file structure and the controllers are added to the controller package, models are added to model package

## Disadvantages
- Less changable, as follows `MVC` pattern
- Lots of `init()` function, all are initiated when the application is ran
- lots of controllers and models can make the file structure messy.
- Hard to explain things, for example you can see things like
    - web.Run(":"), and then what it runs where are the routers ? as previously mentioned, there are lots of init() functions lot of things at a first glance looks like magic

## Changes essential to this structure for cimux
- drop models functionalities
    - we have separate dbapi
    - can be used to define some models
- add service layers instead
    - to communicate with dbapi