Fluxo de Execução e Princípios do Framework
O framework GoFrame segue um processo estruturado para inicialização e tratamento de requisições. Aqui estão os pontos-chave:
- Ordem de Inicialização: O processo começa com a importação de pacotes, seguida pela execução das funções
init()de cada pacote, e finalmente a funçãomain(). - Cadeia de Middleware: As requisições passam pelos middlewares na ordem de registro, enquanto as respostas retornam na ordem inversa.
- Correspondência de Rotas: A correspondência é feita com base no caminho da URL e no método HTTP, garantindo precisão.
- Ciclo de Vida da Requisição: Inclui desde o recebimento até a conclusão da resposta, abrangendo todas as etapas de processamento.
- Tratamento de Erros: Os erros são gerenciados tanto nos middlewares quanto nos controladores para robustez.
Detalhes sobre o processo de importação:
- Importação recursiva de todas as dependências.
- Inicialização de variáveis em nível de pacote.
- Execução das funções
init()de cada pacote.
Aspectos Essenciais para Desenvolvedores
Compreenda os seguintes mecanismos do GoFrame:
- O registro de rotas ocorre imediatamente, vinculando URLs a métodos de controlador, mas a invocação do controlador é adiada até uma requisição correspondente.
- O método
s.Group()executa seu callback instantaneamente para registrar regras de rota. - Os métodos de controlador só são chamados quando uma requisição HTTP é correspondida.
- Os middlewares são executados sequencialmente durante a requisição, não no momento do registro.
Inicialização e Configuração do Servidor
Quando um programa Go inicia, as constantes e variáveis em nível de pacote são inicializadas primeiro, seguidas pelas funções init() na ordem de importação.
Após a inicialização, a função main() é executada. Aqui, o servidor padrão é obtido via g.Server(), e configurações básicas como porta e diretórios estáticos são definidas.
Registro de Componentes e Início do Servidor
Middlewares: Use s.Use() para registrar middlewares globais, como CORS, autenticação e logging. Eles processam requisições antes do roteamento.
Rotas: Utilize s.Group() para definir grupos de rotas, associando caminhos a métodos de controlador. Esses métodos são executados apenas quando há correspondência.
Após o registro, chame s.Run() para iniciar o servidor, que ficará bloqueado escutando requisições na porta configurada.
Ciclo de Vida da Requisição HTTP
- Filtragem por Middleware: A requisição passa por todos os middlewares registrados globalmente.
- Correspondência de Rota: O URL e o método HTTP são usados para localizar a rota e o controlador correspondentes.
- Execução da Lógica de Negócio: O método do controlador é invocado, processando a lógica e retornando uma resposta.
- Retorno da Resposta: A resposta é tratada pelos middlewares antes de ser enviada ao cliente.
Para uma inicialização explícita, consulte a documentação oficial. O framework também suporta reinicialização suave para atualizações sem interrupção.
Desenvolvimento com GoFrame
Assegure uma estrutura de projeto adequada. Para criar um novo projeto, use comandos como:
go mod init nome-do-projeto
go get -u -v github.com/gogf/gf/v2
go mod tidy
Para utilizar a estrutura de diretórios recomendada pelo GoFrame, instale a ferramenta CLI e inicialize o projeto:
go install github.com/gogf/gf/cmd/gf/v2@latest
gf init nome-do-app
gf up
cd nome-do-app && gf run main.go
Exemplo básico de código para um aplicativo:
package main
import (
"log"
"github.com/gogf/gf/v2"
)
func main() {
log.Printf("GoFrame versão: %s", gf.VERSION)
}
Trabalhando com Banco de Dados e DAOs
Ao criar tabelas no banco de dados, utilize o comando gf gen dao para gerar camadas de acesso a dados. Isso produz arquivos em diretórios específicos:
internal/model/do/para estruturas de escrita de dados.internal/model/entity/para estruturas de leitura de dados.internal/dao/para objetos de acesso a dados extensíveis.internal/dao/internal/para implementações internas, não expostas.
Personalize os caminhos de geração no arquivo de configuração YAML:
dao:
- link: "mysql:usuario:senha@tcp(localhost:3306)/nome_do_banco"
path: "./internal"
daoPath: "/dao/plataforma"
Definindo APIs e Controladores
Para criar APIs, defina interfaces em api/usuarios/v1/. Use gf gen ctrl para gerar controladores correspondentes. A lógica de negócio é implementada em internal/logic/.
Regras de validação e internacionalização podem ser configuradas nos arquivos de API e na pasta manifest/i18n/.
Leitura e Escrita de Dados
Utilize as estruturas do para operações de escrita e entity para leitura. Os dados fluem através dessas camadas, garantindo separação de responsabilidades.
Funções Utilitárias Comuns
Aqui estão algumas funções úteis adaptadas para o desenvolvimento:
package utils
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
// Verifica se um elemento existe em um slice.
func ItemPresentInList[T comparable](slice []T, target T) bool {
for _, item := range slice {
if item == target {
return true
}
}
return false
}
// Estrutura padrão para respostas JSON.
type ApiResp struct {
Status int `json:"status"`
Message string `json:"message"`
Payload interface{} `json:"payload"`
}
// Envia uma resposta JSON.
func SendJson(resp *ghttp.Request, status int, message string, payload ...interface{}) {
data := interface{}(nil)
if len(payload) > 0 {
data = payload[0]
}
resp.Response.WriteJson(ApiResp{
Status: status,
Message: message,
Payload: data,
})
}
// Envia uma resposta JSON e encerra a requisição.
func SendJsonAndExit(resp *ghttp.Request, status int, message string, payload ...interface{}) {
SendJson(resp, status, message, payload...)
resp.Exit()
}
Parra tratamento de erros, funções auxiliares podem ser usadas:
package errlib
import (
"context"
"github.com/gogf/gf/v2/frame/g"
)
// Lança um erro se não for nulo.
func ErrIsNil(ctx context.Context, err error, msg ...string) {
if err != nil {
g.Log().Error(ctx, err.Error())
if len(msg) > 0 {
panic(msg[0])
}
panic(err.Error())
}
}
Outros utilitários incluem manipulação de arquivos, criptografia e serviços HTTP, que podem ser adaptados conforme necessário.