All skills
gogf avatar

/goframe-v2

@911705d
by GoFramegogf/skills81 stars
3

GoFrame v2 development skill. Use only when the target Go project uses or is explicitly adopting GoFrame v2: the nearest go.mod requires github.com/gogf/gf/v2, existing Go files import github.com/gogf/gf/v2 or any github.com/gogf/gf/v2/... component package, or the user asks to scaffold, migrate, or build with GoFrame. Trigger for GoFrame-backed Go work such as APIs/controllers/services, middleware, routing/config, ORM/DAO/DO/entity/database operations, gf CLI/codegen, HTTP/gRPC services, and microservice conventions. Do not trigger for generic Go projects without GoFrame evidence, frontend-only work, shell scripts, or unrelated infrastructure tasks.

Use this Skill: https://skilld.dev/gh/gogf/skills/goframe-v2

This session only. Nothing lands on disk.

references快速开始使用规范路由.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

为了简化路由注册方式,避免一些繁琐的参数处理细节, 让开发者将精力聚焦于业务逻辑本身,GoFrame框架提供了规范化的路由注册方式。 规范化的路由注册方式,我们为了见名知意,便命名为了规范路由。

数据结构定义

在规范路由中,我们同样定义一个请求的数据结构来接收客户端提交的参数信息,但同时需要定义一个返回对象。 目的是为了未来返回参数扩展的需要,以及未来标准化接口文档生成的需要。

type HelloReq struct {
    g.Meta `path:"/" method:"get"`
    Name   string `v:"required" dc:"姓名"`
    Age    int    `v:"required" dc:"年龄"`
}
type HelloRes struct {}

简要介绍:

  • 在请求对象中,我们多了一个g.Meta对象的引用,并给定了一些结构体标签。该对象为元数据对象,用于给结构体嵌入 一些定义的标签信息。例如在本示例中:
    • path:表示注册的路由地址。
    • method:表示注册绑定的HTTP Method。
  • 在属性中同样出现两个新的标签名称:
    • v:表示校验规则,为valid的缩写,用于自动校验该参数。这里使用v:"required"表示该参数为必需参数,如果客户端未传递该参数时,服务端将会校验失败。
    • dc:表示参数描述信息,为description的缩写,用于描述该参数的含义。

:::info 在开发手册的对应章节中,有关于全部标签信息以及校验组件的详细讲解,这里只需要了解其作用即可,不做过多介绍。 :::

路由对象管理

为了更好地管理路由注册,特别是接口比较多的场景下,如果手动一一去配置路由与路由函数关系太过于繁琐。 我们通过对象化的形式来封装路由函数,通过对象化封装的方式来简化我们的路由管理。 我们定义一个路由对象如下:

type Hello struct{}

func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
    r := g.RequestFromCtx(ctx)
    r.Response.Writef(
        "Hello %s! Your Age is %d",
        req.Name,
        req.Age,
    )
    return
}
  • 我们定义了一个Hello对象,该对象用于封装路由函数,其所有定义的公开方法都将被作为路由函数进行注册。
  • 可以看到该路由对象的Say方法的路由函数的定义方式,相比较于func(*ghttp.Request)的路由函数定义方式,更符合业务逻辑函数的定义风格。
  • 在路由回调方法Say中,我们通过g.RequestFromCtx方法从ctx获取原始的*ghttp.Request请求对象,用于自定义返回内容数据。

完整示例代码

我们调整我们前面的Web Server程序如下:

package main

import (
    "context"

    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"
)

type HelloReq struct {
    g.Meta `path:"/" method:"get"`
    Name   string `v:"required" dc:"姓名"`
    Age    int    `v:"required" dc:"年龄"`
}
type HelloRes struct{}

type Hello struct{}

func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
    r := g.RequestFromCtx(ctx)
    r.Response.Writef(
        "Hello %s! Your Age is %d",
        req.Name,
        req.Age,
    )
    return
}

func main() {
    s := g.Server()
    s.Group("/", func(group *ghttp.RouterGroup) {
        group.Bind(
            new(Hello),
        )
    })
    s.SetPort(8000)
    s.Run()
}

在本示例中:

  • 通过s.Group的分组路由方式定义一组路由注册,在其回调方法中注册的所有路由,都会带有其定义的分组路由前缀/。
  • 通过group.Bind方法注册路由对象,该方法将会遍历路由对象的所有公开方法,读取方法的输入输出结构体定义,并对其执行路由注册。

执行结果

运行后,我们访问 http://127.0.0.1:8000/?name=john&age=18 可以看到,页面输出结果符合预期。

我们尝试一下错误的参数请求 http://127.0.0.1:8000/ 但我们发现,页面没有输出任何的结果? 这是由于参数校验失败,并未进入到我们的路由函数中,而是被Server直接返回了。

学习小结

在本章节我们学会了规范的路由注册方式,但是还缺少对返回结果,特别是产生错误之后的统一处理控制。

那么,我们应该如何捕获校验失败错误并自定义返回数据呢?我们将在下一章节更进一步介绍。

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk MEDIUM
  • Gen Agent Trust Hub16d

    The skill provides a comprehensive development guide and code examples for the GoFrame v2 framework. While highly informative for Go developers, it contains several examples with hardcoded placeholder secrets, tokens, and specific local file paths to sensitive configuration files (like Kubernetes credentials). These elements are provided for demonstration purposes but represent insecure practices if used in production without modification.

  • Socket16d

    5 alerts: gptSecurity, gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    227/949 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 911705d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 4 months ago.

Steadyupdated 4 months ago
  • Go
  • Database
  • goframe
  • orm
  • http
  • grpc
  • microservices
  • crud
  • scaffolding
  • middleware

README badge

README badge for gogf/skills

Provides instruction and conventions for developing with GoFrame v2, a modular Go framework for building HTTP and gRPC services, microservices, and database operations using its ORM, CLI tooling, and project scaffolding. Use this skill when the target project has GoFrame v2 as a dependency or when the user requests scaffolding, migrations, or service development with GoFrame conventions.

Generated from the current SKILL.md.

When should I use this skill?
Use this skill only when your Go project uses GoFrame v2, indicated by github.com/gogf/gf/v2 in go.mod or imports. Do not use for generic Go projects, frontend work, or infrastructure tasks unrelated to GoFrame.
Should I manually set created_at and updated_at fields?
No. GoFrame automatically writes created_at on insert and updated_at on insert/update/save. Manually setting these fields is redundant and violates project conventions.
What should I use for database operations instead of g.Map?
Always use DO objects from internal/model/do/. DO struct fields are interface{}, unset fields remain nil and are automatically ignored by the ORM.
How does soft delete work in GoFrame?
Call Delete() on the DAO; GoFrame automatically converts it to UPDATE SET deleted_at = NOW(). Queries automatically filter out soft-deleted rows without requiring manual WhereNull conditions.
Where should I implement business logic?
Implement business logic directly in the service/ directory. Do not use the logic/ directory unless explicitly requested.

Generated from the current SKILL.md. These answers refresh after source changes.