Go is one of the most used backend development languages actually, which has many advantages. This language currently has several frameworks, each with different learning curves and different advantages. In this article I will show you how to make an api rest using beego and that connects to a postgresql database.
Why Beego.
the beego framework is used for api rest, web applications and backend services in golang, it can be similar to Django which is a python framework, beego does not require third party installations, it handles Model-View-Controller (MVC) architecture, additionally it has a command line interface (CLI) called Bee Tool.
It integrates the Object Relationship Map (ORM) that helps to organize the application's database along with the session management tools and registration systems. It also incorporates a cache driver and libraries to operate HTTP elements. Another great feature is that it works well with command line tools.
Due to its extensive features and functionality it is not a tool that is usually used by beginners
Table of contents
- Installation of beego and bee tool
- Creation of api using bee tool
- db model
- create api
- Additional adjustments to the api
- Run Api
- Use api
- Enable Cors
- Use of swagger
you can access the project repository
Installation
you need go version >= 1.14 .
# allow downloading of go modules
go env -w GO111MODULE=on
# installation of beego
go get github.com/beego/beego/v2
# bee tool installation
go get github.com/beego/bee/v2
no further steps are needed to install beego, you can verify the installation by running bee version
on your computer, you should see something like the following:
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v2.0.2
├── Beego : Beego is not installed. Please do consider installing it first: https://github.com/beego/beego/v2. If you are using go mod, and you don't install the beego under $GOPATH/src/github.com/astaxie, just ignore this.
├── GoVersion : go1.15
├── GOOS : linux
├── GOARCH : amd64
├── NumCPU : 8
├── GOPATH : /go
├── GOROOT : /usr/local/go
├── Compiler : gc
└── Date : Monday, 18 Jan 2021
you can ignore the line that says Beego is not installed
Creation of api using bee tool
For this example, a small hero data model will be provided
Data model
Creation api
To integrate with github and be able to use native go commands to get modules it is recommended to create the project in the following path
${GOPATH}/src/github.com/[user name or organization name]
in my case
${GOPATH}/src/github.com/BOTOOM
for the creation of the api use the following command
bee api heroes_crud -driver=postgres -conn="postgres://[database user]:[database password]@[database host or url]:[optionar database port]/[database name]?sslmode=disable"
in my case
bee api heroes_crud -driver=postgres -conn="postgres://postgres:docker@192.168.0.17:5432/heroes?sslmode=disable"
After executing the command you will see something similar
your project will have a structure similar to this
Additional adjustments to the api
the api was already created using bee tool, but it is possible that errors are generated when creating the api so follow these steps
Adjustment of routes in imports
before
heroes_crud
addgithub.com/[user name or organization name]/
before change in the
main.go
fileimport ( _ "heroes_crud/routers" beego "github.com/beego/beego/v2/server/web" "github.com/beego/beego/v2/client/orm" _ "github.com/lib/pq" )
after change
main.go
import ( _ "github.com/BOTOOM/heroes_crud/routers" beego "github.com/beego/beego/v2/server/web" "github.com/beego/beego/v2/client/orm" _ "github.com/lib/pq" )
verify that the file
routers/router.go
contains the correct import, usually it is generated correctly ,for examplepackage routers import ( "github.com/BOTOOM/heroes_crud/controllers" beego "github.com/beego/beego/v2/server/web" )
finally check the same in the drivers
publisher.go
,hero.go
and `power.goSetting go.mod
since go currently works with modules we must make a similar adjustment to the previous one but in the
go.mod
filemodule heroes_crud
make the following change
module github.com/BOTOOM/heroes_crud
database connection setting
beego version 2 has had several changes among those to obtain the variables from the configuration file `conf/app.conf` , to avoid database connection errors make the following change in the `main.go
func main() { orm.RegisterDataBase("default", "postgres", beego.AppConfig.String("sqlconn")) if beego.BConfig.RunMode == "dev" { beego.BConfig.WebConfig.DirectoryIndex = true beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger" } beego.Run() }
creation of the variable
sqlconn
func main() { sqlconn, _ := beego.AppConfig.String("sqlconn") orm.RegisterDataBase("default", "postgres", sqlconn) if beego.BConfig.RunMode == "dev" { beego.BConfig.WebConfig.DirectoryIndex = true beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger" } beego.Run() }
Auto-incremental id setting for the id to be auto-incremental when making post requests add in the struct of each model
;auto
afterpk
should be something like this, for the model ofpublisher.go
:type Publisher struct { Id int `orm:"column(id);pk;auto"` Name string `orm:"column(name)"` Active bool `orm:"column(active);null"` CreateIn time.Time `orm:"column(create_in);type(timestamp without time zone);null"` }
do the same for the other models.
Addition of RelatedSel() method
beego has a method called
RelatedSel
that takes a foring key and makes a join in order to bring the data and not have to make another nested query, this function has a capacity of 5 levelsto make use of it in the respective models in the
GetAll
method as an example in thehero.go
model theGetAllHero
methodbefore the change
// GetAllHero retrieves all Hero matches certain condition. Returns empty list if // no records exist func GetAllHero(query map[string]string, fields []string, sortby []string, order []string, offset int64, limit int64) (ml []interface{}, err error) { o := orm.NewOrm() qs := o.QueryTable(new(Hero))
after change
// GetAllHero retrieves all Hero matches certain condition. Returns empty list if // no records exist func GetAllHero(query map[string]string, fields []string, sortby []string, order []string, offset int64, limit int64) (ml []interface{}, err error) { o := orm.NewOrm() qs := o.QueryTable(new(Hero)).RelatedSel()
Run Api
To run the api run the following command at the root of the project
bee run
or
go run main.go
open your browser in localhost:8080 , podrá ver lo siguiente:
Use Api
you can use postman to make use of the api, for example to join a new publisher use a POST request, the endpoint http://localhost:8080/v1/publisher
and the following body
{
"Name": "Dc Comics",
"Active": true
}
using postman
result using postman, the same endpoint is used for the GET method
you can use in the same endpoint the PUT
and DELETE
methods
Enable CORS
To enable cors copy the following lines into the main function of the main.go
file this will allow the api to be consumed from web applications or other backend services
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowOrigins: []string{"*"},
AllowMethods: []string{"PUT", "PATCH", "GET", "POST", "OPTIONS", "DELETE"},
AllowHeaders: []string{"Origin", "x-requested-with",
"content-type",
"accept",
"origin",
"authorization",
"x-csrftoken"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
}))
It should look something like this:
package main
import (
_ "github.com/BOTOOM/heroes_crud/routers"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/server/web/filter/cors"
_ "github.com/lib/pq"
)
func main() {
sqlconn, _ := beego.AppConfig.String("sqlconn")
orm.RegisterDataBase("default", "postgres", sqlconn)
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowOrigins: []string{"*"},
AllowMethods: []string{"PUT", "PATCH", "GET", "POST", "OPTIONS", "DELETE"},
AllowHeaders: []string{"Origin", "x-requested-with",
"content-type",
"accept",
"origin",
"authorization",
"x-csrftoken"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
}))
beego.Run()
}
verify that the cors are imported from "github.com/beego/beego/v2/server/web/filter/cors"
Use Swagger
Swagger is an apis documentation tool which can also be used for apis testing. To enable and create swagger files in your project run the following command in your terminal
bee run -downdoc=true -gendoc=true
open your browser in localhost:8080/swagger/ and see the following
at the end you will find the data models
to use swagger you just need to display the method you want to use by clicking on the Try it Out
button and then on Execute
The result will be displayed there
Use of filters with swagger
The GetAll method generated with the api allows to make filters and queries which we can test from swagger.
For this example I have entered 2 super heroes Batman and Ironman, when performing the get method gives me the following answer
There we can see the data of the heroes but additionally we can see what their editorial brings , that is possible thanks to the method RelatedSel()
that we previously configured.
Next we will make use of the filters to obtain only the super heroes of Dc Comics
.
and the result will be
You can see that also in the section of 'Curl' at the beginning provides the request if used in any application.
Additionally you can use the other parameters like limit
, offset
, request only some fields using fields
and be able to sort your results
Conclusion
Beego is a golang framework with a large amount of features and high functionality that allows developers to build a robust REST API in a short time and which can be strengthened by using documentation.
additionally be able to access: