Skip to main content
gFly v1.15.1
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Tour of gFly

One thing is for sure that you have completed the article instructions Installation 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:

Start app

# Run docker instances for Database, Redis, Mail
make docker.run

# Run web in local
make doc
make dev

Check browser http://localhost:7789/

Create a HelloPage

Controller

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>")
}

Define router

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())
}

Checking

Browse http://localhost:7789/hello

Create a HelloAPI

Controller

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)
}

Define router

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())
    })
}

Checking

Browse http://localhost:7789/api/v1/hello

Or terminal

curl -v -X GET http://localhost:7789/api/v1/hello | jq

Service connection

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.

1. Connect Database service

Import initial tables

make migrate.up

Note: Check DB connection and see 4 tables: users, roles, user_roles, and address.

Create command

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 and run command

# Build
make build

# Run command `db-test`
./build/artisan cmd:run db-test

2. Connect Cache service

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 and run command

# Build
make build

# Run command `redis-test`
./build/artisan cmd:run redis-test

3. Send Mail service

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"))
}
Note
We have used notification Mail app/notifications/send_mail_notification.go in this example. You can ignore notification at this point. Will explain more later.

Build and run command

# Build
make build

# Run command `mail-test`
./build/artisan cmd:run mail-test

Check mail at http://localhost:8025/