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.

referencesWEB服务开发接口文档接口文档-OpenAPIv3.md

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

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

:::tip OpenAPIv3 协议主要使用在规范路由中,阅读接口文档协议介绍之前,请先了解一下规范路由: 路由注册-规范路由 :::

一、 OpenAPIv3

详细的 OpenAPIv3 协议介绍请参考: https://swagger.io/specification/

二、 g.Meta 元数据

接口的元数据信息可以通过为输入结构体embedded方式嵌入g.Meta结构,并通过g.Meta的属性标签方式来实现。

关于元数据组件的介绍,详情请参考章节: 元数据-gmeta

三、常用协议标签

输入输出结构体中的属性的标签完整支持 OpenAPIv3 协议,因此只要增加了对应的协议标签,那么生成的 OpenAPIv3 接口信息中将会自动包含该属性。

大部分的标签属性已经被 Server 组件自动生成,开发者需要手动设置的标签不多。

1、基础标签

常见的基础标签包括:

常见标签 说明 备注
path 结合注册时的前缀共同构成接口URI路径 用于 g.Meta 标识接口元数据
tags 接口所属的标签,用于接口分类 用于 g.Meta 标识接口元数据
method 接口的请求方式: ALL/GET/PUT/POST/DELETE...(不区分大小写)。支持组合方式如GET,POST,多种方式使用,分隔。 用于 g.Meta 标识接口元数据
deprecated 标记该接口废弃 用于 g.Meta 标识接口元数据
summary 接口/参数概要描述 缩写 sm
description 接口/参数详细描述 缩写 dc
in 参数的提交方式 header/path/query/cookie
default 参数的默认值 缩写 d
mime 接口的 MIME 类型,例如 multipart/form-data 一般是全局设置,默认为 application/json。 用于 g.Meta 标识接口元数据
type 参数的类型,一般不需要设置,特殊参数需要手动设置,例如 file 仅用于参数属性
:::tip
更多标签请参考标准的 OpenAPIv3 协议: https://swagger.io/specification/
:::
<!-- 除此之外,响应结构体的 `g.Meta` 还支持额外的标签以设置更详细的文档信息: | 标签 | 说明 | 备注 | | --- | --- | --- | | `status` | 设置响应的默认返回状态码 | 用于 `g.Meta` 标识接口元数据,默认值为 `200` | | `responseExample` | 设置响应的默认返回示例的 `json` 文件路径 | 用于 `g.Meta` 标识接口元数据,缩写 `resEg` | `responseExample` 支持的 `json` 文件格式如下: <Tabs> <TabItem value="array" label="Array"> ```json [ { "code": 0, "message": "Success", "data": null }, { "code": 1, "message": "Internal Server Error", "data": null } ] ``` </TabItem> <TabItem value="object" label="Object"> ```json { "success": { "code": 0, "message": "Success", "data": null }, "error": { "code": 1, "message": "Internal Server Error", "data": null } } ``` </TabItem> </Tabs> -->

2、扩展标签

在 OpenAPI 规范里面,所有名称以 x- 开头的标签是开发者可自定义的扩展标签。扩展标签可以在任意的接口、属性中以 Golang struct tag 的形式定义,在接口文档生成时,将会作为独立的字段返回。例如:

package main

import (
    "context"

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

type GetListReq struct {
    g.Meta `path:"/user" tags:"User" method:"get" x-group:"User/Info" summary:"Get user list with basic info."`
    Page   int `dc:"Page number" d:"1" x-sort:"1"`
    Size   int `dc:"Size for per page." d:"10" x-sort:"2"`
}
type GetListRes struct{}

type Controller struct{}

func (c *Controller) GetList(ctx context.Context, req *GetListReq) (res *GetListRes, err error) {
    return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func main() {
    s := g.Server()
    s.Group("/", func(group *ghttp.RouterGroup) {
        group.Bind(new(Controller))
    })
    s.SetOpenApiPath("/api.json")
    s.SetSwaggerPath("/swagger")
    s.SetPort(8199)
    s.Run()
}

执行后,访问地址 http://127.0.0.1:8199/swagger 可以查看 swagger ui,访问 http://127.0.0.1:8199/api.json 可以查看对应的 OpenAPIv3 接口文档。其中生成的 OpenAPIv3 接口文档如下:

{
    "openapi": "3.0.0",
    "components": {
        "schemas": {
            "main.GetListReq": {
                "properties": {
                    "Page": {
                        "default": 1,
                        "description": "Page number",
                        "format": "int",
                        "properties": {},
                        "type": "integer",
                        "x-sort": "1"
                    },
                    "Size": {
                        "default": 10,
                        "description": "Size for per page.",
                        "format": "int",
                        "properties": {},
                        "type": "integer",
                        "x-sort": "2"
                    }
                },
                "type": "object",
                "x-group": "User/Info"
            },
            "main.GetListRes": {
                "properties": {},
                "type": "object"
            }
        }
    },
    "info": {
        "title": "",
        "version": ""
    },
    "paths": {
        "/user": {
            "get": {
                "parameters": [
                    {
                        "description": "Page number",
                        "in": "query",
                        "name": "Page",
                        "schema": {
                            "default": 1,
                            "description": "Page number",
                            "format": "int",
                            "properties": {},
                            "type": "integer",
                            "x-sort": "1"
                        },
                        "x-sort": "1"
                    },
                    {
                        "description": "Size for per page.",
                        "in": "query",
                        "name": "Size",
                        "schema": {
                            "default": 10,
                            "description": "Size for per page.",
                            "format": "int",
                            "properties": {},
                            "type": "integer",
                            "x-sort": "2"
                        },
                        "x-sort": "2"
                    }
                ],
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/main.GetListRes"
                                }
                            }
                        },
                        "description": ""
                    }
                },
                "summary": "Get user list with basic info.",
                "tags": [
                    "User"
                ],
                "x-group": "User/Info"
            },
            "x-group": "User/Info"
        }
    }
}

可以看到,扩展标签已经生成到了接口文档中。

四、数据校验规则自动转换

GoFrame的goai组件能够自动将结构体字段的数据校验规则(validation rules)转换为OpenAPIv3中对应的校验数据结构,使接口文档更加准确和完整。这意味着您只需在结构体字段中定义常规的数据校验规则,goai组件就会自动将其转换为OpenAPIv3规范中的对应约束。

1. 支持的校验规则

以下是goai组件自动识别并转换的校验规则:

校验规则 说明 OpenAPIv3对应结构
required 必填字段 required: true
min:{数值} 最小值限制 minimum: {数值}
max:{数值} 最大值限制 maximum: {数值}
length:{最小长度},{最大长度} 字符串长度范围 minLength: {最小长度}, maxLength: {最大长度}
min-length:{长度} 字符串最小长度 minLength: {长度}
max-length:{长度} 字符串最大长度 maxLength: {长度}
between:{最小值},{最大值} 数值范围 minimum: {最小值}, maximum: {最大值}
in:{值1},{值2},... 枚举值限制 enum: [{值1}, {值2}, ...]

2. 使用示例

type CreateUserReq struct {
    g.Meta  `path:"/user" method:"post" summary:"创建用户"`
    Name    string `v:"required|length:2,30" dc:"用户名"`
    Age     int    `v:"required|between:18,60" dc:"年龄"`
    Email   string `v:"required|email" dc:"电子邮箱"`
    Score   int    `v:"min:0|max:100" dc:"分数"`
    Type    string `v:"in:admin,user,guest" dc:"用户类型"`
}

生成的OpenAPIv3文档将包含以下校验信息:

  • Name字段:required: true, minLength: 2, maxLength: 30
  • Age字段:required: true, minimum: 18, maximum: 60
  • Email字段:required: true
  • Score字段:minimum: 0, maximum: 100
  • Type字段:enum: ["admin", "user", "guest"]

3. 注意事项

  • 数值类型(如int、float等)的字段才会转换min、max和between规则为minimum和maximum
  • 字符串类型的字段会转换min-length、max-length和length规则为minLength和maxLength
  • required规则会转换为参数的required: true属性
  • in规则会转换为enum数组,如果所有值都是数字,则会转换为数字类型的枚举,否则为字符串类型

五、扩展 OpenAPIv3 信息

核心的接口信息已经自动生成,如果开发者想要更进一步完善接口信息,可以通过 s.GetOpenApi() 接口获取到 OpenAPIv3 的结构体对象,并手动填充对应的属性内容即可。我们来看一个示例,在该示例中,我们设计每个接口外层公共的数据结构:

我们可以发现通过通用的 OpenAPIv3 对象我们可以自定义修改其内容,并且根据它生成其他各种自定义类型的接口文档。

五、添加api.json(swagger)自定义鉴权

对于需要进行api文档鉴权的情况,可以使用 ghttp.BindHookHandler 方法对 s.GetOpenApiPath() 路由绑定前置方法进行鉴权,示例如下:

func main() {
    s := g.Server()
    // if api.json requires authentication, add openApiBasicAuth handler
    s.BindHookHandler(s.GetOpenApiPath(), ghttp.HookBeforeServe, openApiBasicAuth)
    s.Run()
}

func openApiBasicAuth(r *ghttp.Request) {
    if !r.BasicAuth("OpenApiAuthUserName", "OpenApiAuthPass", "Restricted") {
        r.ExitAll()
        return
    }
}

详细介绍请参考代码示例文档:swagger-auth

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.