Tour of gFly
One thing is for sure that you have completed the article instructions in the best way.
Let open the source with any your favorite IDEs: GoLand, VSCode, NeoVim…
We will experiment with the example of creating a page HelloPage and an API HelloApi controllers.
First of all. Need to start your application by below command:
# Run docker instances for Database, Redis, Mail
make docker.run
# Run web in local
make doc
make dev
Check browser http://localhost:7789/
Create file hello_page.go in folder app/http/controllers/page/
package page
import "github.com/gflydev/core"
// ====================================================================
// ======================== Controller Creation =======================
// ====================================================================
// NewHelloPage As a constructor to create a Home Page.
func NewHelloPage() *HelloPage {
return &HelloPage{}
}
type HelloPage struct {
BasePage
}
// ====================================================================
// ========================= Request Handling =========================
// ====================================================================
// Handle processes HTTP requests for the Hello page.
func (m *HelloPage) Handle(c *core.Ctx) error {
return c.HTML("<h2>Hello world</h2>")
}
Declare HelloPage into app/http/routes/web_routes.go
package routes
import (
"gfly/app/http/controllers/page"
"github.com/gflydev/core"
)
// WebRoutes func for describe a group of Web page routes.
func WebRoutes(r core.IFly) {
r.GET("/hello", page.NewHelloPage())
}
Browse http://localhost:7789/hello
Create file hello_api.go in folder app/http/controllers/api/
package api
import (
"github.com/gflydev/core"
"github.com/gflydev/core/utils"
)
// ====================================================================
// ======================== Controller Creation =======================
// ====================================================================
// NewHelloApi As a constructor to create new API.
func NewHelloApi() *HelloApi {
return &HelloApi{}
}
// HelloApi API struct.
type HelloApi struct {
core.Api
}
// ====================================================================
// ========================= Request Handling =========================
// ====================================================================
// Handle Process main logic for API.
// @Summary Get API info
// @Description Get API server information
// @Tags Misc
// @Accept json
// @Produce json
// @Success 200 {object} response.ServerInfo
// @Router /hello [get]
func (h *HelloApi) Handle(c *core.Ctx) error {
obj := make(core.Data).
Set("name", utils.Getenv("API_NAME", "gfly")).
Set("server", utils.Getenv("APP_URL", "http://localhost:7789"))
return c.JSON(obj)
}
Declare HelloApi into app/http/routes/api_routes.go
package routes
import (
"gfly/app/http/controllers/api"
"github.com/gflydev/core"
"github.com/gflydev/core/utils"
)
// ApiRoutes func for describe a group of API routes.
func ApiRoutes(r core.IFly) {
prefixAPI := fmt.Sprintf(
"/%s/%s",
utils.Getenv("API_PREFIX", "api"),
utils.Getenv("API_VERSION", "v1"),
)
// API Routers
r.Group(prefixAPI, func(apiRouter *core.Group) {
// curl -v -X GET http://localhost:7789/api/v1/hello | jq
apiRouter.GET("/hello", api.NewHelloApi())
})
}
Browse http://localhost:7789/api/v1/hello
Or terminal
curl -v -X GET http://localhost:7789/api/v1/hello | jq
You have experienced how to create API HelloApi, Page HelloPage as well as how to add them to the router. As simple and easy as that, connecting and interacting with Database, Cache or sending Mail is not a big problem. Now we try to create 3 commands running with CLI to test the connection with external services.
make migrate.up
Note: Check DB connection and see 4 tables: users, roles, user_roles, and address.
Create a new command line db-test. Add file app/console/commands/db_command.go
package commands
import (
"gfly/app/domain/models"
"github.com/gflydev/console"
"github.com/gflydev/core/log"
mb "github.com/gflydev/db"
"time"
)
// ---------------------------------------------------------------
// Register command.
// ./artisan cmd:run db-test
// ---------------------------------------------------------------
// Auto-register command.
func init() {
console.RegisterCommand(&dbCommand{}, "db-test")
}
// ---------------------------------------------------------------
// DBCommand struct.
// ---------------------------------------------------------------
// DBCommand struct for hello command.
type dbCommand struct {
console.Command
}
// Handle Process command.
func (c *dbCommand) Handle() {
user, err := mb.GetModelBy[models.User]("email", "admin@gfly.dev")
if err != nil || user == nil {
log.Panic(err)
}
log.Infof("User %v\n", user)
log.Infof("DBCommand :: Run at %s", time.Now().Format("2006-01-02 15:04:05"))
}
# Build
make build
# Run command `db-test`
./build/artisan cmd:run db-test
Create a new command line redis-test. Add file app/console/commands/redis_command.go
package commands
import (
"github.com/gflydev/cache"
"github.com/gflydev/console"
"github.com/gflydev/core/log"
"time"
)
// ---------------------------------------------------------------
// Register command.
// ./artisan cmd:run redis-test
// ---------------------------------------------------------------
// Auto-register command.
func init() {
console.RegisterCommand(&redisCommand{}, "redis-test")
}
// ---------------------------------------------------------------
// RedisCommand struct.
// ---------------------------------------------------------------
// RedisCommand struct for hello command.
type redisCommand struct {
console.Command
}
// Handle Process command.
func (c *redisCommand) Handle() {
// Add new key
if err := cache.Set("foo", "Hello world", time.Duration(15*24*3600)*time.Second); err != nil {
log.Error(err)
}
// Get data key
bar, err := cache.Get("foo")
if err != nil {
log.Error(err)
}
log.Infof("foo `%v`\n", bar)
log.Infof("RedisCommand :: Run at %s", time.Now().Format("2006-01-02 15:04:05"))
}
# Build
make build
# Run command `redis-test`
./build/artisan cmd:run redis-test
Create a new command line mail-test. Add file app/console/commands/mail_command.go
package commands
import (
"gfly/app/notifications"
"github.com/gflydev/console"
"github.com/gflydev/core/log"
"github.com/gflydev/notification"
"time"
)
// ---------------------------------------------------------------
// Register command.
// ./artisan cmd:run mail-test
// ---------------------------------------------------------------
// Auto-register command.
func init() {
console.RegisterCommand(&mailCommand{}, "mail-test")
}
// ---------------------------------------------------------------
// MailCommand struct.
// ---------------------------------------------------------------
// MailCommand struct for hello command.
type mailCommand struct {
console.Command
}
// Handle Process command.
func (c *mailCommand) Handle() {
// ============== Send mail ==============
sendMail := notifications.SendMail{
Email: "admin@gfly.dev",
}
if err := notification.Send(sendMail); err != nil {
log.Error(err)
}
log.Infof("MailCommand :: Run at %s", time.Now().Format("2006-01-02 15:04:05"))
}
NoteWe have used notification Mailapp/notifications/send_mail_notification.goin this example. You can ignore notification at this point. Will explain more later.
# Build
make build
# Run command `mail-test`
./build/artisan cmd:run mail-test
Check mail at http://localhost:8025/