7
0
Go to file
2026-03-24 16:53:49 +08:00
sdk 新增同步微信投诉工单接口 2025-12-30 16:55:54 +08:00
services fix(game): 修正白名单和黑名单接口响应码判断 2026-03-24 16:53:49 +08:00
vendor 封装passport修改用户状态接口 2025-09-18 15:08:51 +08:00
.gitignore init project 2020-08-03 20:48:58 +08:00
go.mod 封装passport修改用户状态接口 2025-09-18 15:08:51 +08:00
go.sum 封装passport修改用户状态接口 2025-09-18 15:08:51 +08:00
README.md feat(game/activity_vip_user_new):封装官网白名单、黑名单用户获取 2026-03-24 12:00:19 +08:00

gaore-common-sdk-go

1.目录架构

├── README.md
├── sdk
│   ├── auth                    `认证类`
│   ├── client.go               `客户端主入口类`
│   ├── config.go
│   ├── requests                `请求类`
│   ├── responses               `响应类`
│   └── utils                   `工具类`
└── services
    └── jedi

2.引入

go get -u golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk

或 Go Module

import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"

3.服务端认证及返回处理

调用 auth.UnSign 方法,提供*http.Request请求实例,以及signer.Signer 签名器(签名器需要包括凭据) 即可完成整个验签过程

这里以beego为例 :

package applications

import (
    "github.com/astaxie/beego"
    "github.com/astaxie/beego/context"
    "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
    "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
    "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/signers"
    "golib.gaore.com/GaoreGo/grlogs"
)

func init() {
    // 过滤器
    beego.InsertFilter("/api/*", beego.BeforeRouter, func(context *context.Context) {
        httpRequest := context.Request
        err := auth.UnSign(httpRequest, signers.NewAccessKeySigner(&credentials.AccessKeyCredential{
            AccessKeyId:     "aaaaaa",
            AccessKeySecret: "bbbbbb",
            AccessKeyFrom:   context.Input.Param("access_from"),
        }))

        if err != nil {
            resp := response.NewJsonByDefaultFailed()
            resp.Msg = err.Error()
            resp.Code = 10086

            var (
                hasIndent = beego.BConfig.RunMode != beego.PROD
            )
            context.Output.Status = 500
            context.Output.JSON(resp, hasIndent, false)
        }
    })
}

服务端返回的响应体为以下结构的json字符流, code,status,msg 这三个字段最好要包含且数据类型要一致 , data 部分为业务内容,自行定义

{
    "code": 1001,
    "msg": "不能为空",
    "status": false,
    "data": {
        ...
    }
}

4.sdk编写

services目录下以服务归类新建文件夹, 如jedi为短信服务,以 RpcRequestBaseResponse 以基类写好请求子类和响应子类。一个请求接口对应一对请求和响应类。

import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"

const (
	HOST    = "jedi"  // 如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
	VERSION = "2020-08-04"
)


type Client struct {
	sdk.Client
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
	client = &Client{}
	err = client.InitWithAccessKey(accesskey, secrect, source)
	return
}

func (c *Client) Test(req *DemoTestRequest) (response *DemoTestResponse, err error) {
	response = CreateDemoTestResponse()
	err = c.DoAction(req, response)
	return
}

请求类,对参数用标签解释, 如 position:"Query" field:"param_1" default:"" 有三个字段 position , field, default

  • position 为标志该参数为请求体对应的位置, Query query参数, Body post请求体参数, Head请求头参数

  • field 解释成参数实际名称

  • default 默认值

type DemoTestRequest struct {
    *requests.RpcRequest
    Param1 string `position:"Query" field:"param_1" default:"" `
    Param2 int    `position:"Query" field:"param_2" default:"10086" `
    Param3 bool   `position:"Query" field:"param_3" default:"false" `
}

对应解释成http请求为

GET param_1=111&param_2=10086&param_3=false

完整示例:

package jedi

import (
    "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
    "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

// 定义请求体
type DemoTestRequest struct {
    *requests.RpcRequest
    Param1 string `position:"Query" field:"param_1" default:"" `
    Param2 int    `position:"Query" field:"param_2" default:"10086" `
    Param3 bool   `position:"Query" field:"param_3" default:"false" `
}

func CreateDemoTestRequest() (req *DemoTestRequest) {
    req = &DemoTestRequest{RpcRequest: &requests.RpcRequest{}}
    // InitWithApiInfo 初始化请求,有三个参数,域名,版本,和路径
    // 域名参数如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
    req.InitWithApiInfo(HOST, VERSION, "/api/sms/Index")
    // 定义 请求方法 POST 或 GET
    req.Method = requests.GET
    return
}

// 定义响应体
type DemoTestResponse struct {
    *responses.BaseResponse
    Data DemoTestResponseData `json:"data"`
}

type DemoTestResponseData struct {
    Account string `json:"account"`
    Total   int    `json:"total"`
}

func CreateDemoTestResponse() *DemoTestResponse {
    return &DemoTestResponse{
        BaseResponse: &responses.BaseResponse{},
    }
}

终端调试打开方式, 需要在系统环境变量上加入(三选一):

DEBUG=sdk,signer,request

5.测试用例编写要求

新增或修改 services/* 下的接口封装时,必须配套可编译的测试,并遵循下列约定(风格可参考 services/cs/client_test.goservices/game/client_test.go)。

5.1 单测职责(一条用例里要覆盖什么)

  • 请求侧:构造 Create*Request,填入业务参数后调用 requests.InitParam(req),再断言 HTTP 方法、GetActionName() 路径、以及 Query/Form 等关键参数是否注入正确。
  • 调用侧:使用本服务 NewClient()(或项目约定的构造方式)真实调用 Client 上对应方法,覆盖 DoAction 与签名、序列化整条链路。
  • 响应侧:断言 err == nil、响应非 nil,并对业务字段做断言(如 CodeMsgData 及关键业务 ID、类型等必须通过 fmt.Printf 打印返回内容,便于人工核对逻辑是否正确。
  • 风格:与 cs 一致时优先使用 t.Error / t.Errorf + return 早退出;断言失败时除 t.Errorf 外可再 fmt.Printf("%#+v\n", resp)(及对 *resp.Data)便于排错。

5.2 组织方式

  • 同一能力的多条场景(如白名单与黑名单):可拆成 TestXxxTestXxxBlack 等若干函数,每个函数内仍应完整包含「请求校验 → 真实调用 → 响应断言 → 打印」,避免把断言拆成大量只测一行的小函数。
  • 禁止仅写「只校验 InitParam、不调 Client」的孤立用例作为唯一测试若需 mock无网/CI可另加辅助函数但不应替代上述真实调用用例作为唯一验收。

5.3 输出与可读性

  • 使用 fmt.Printf("%#+v\n", resp) 打印完整响应结构体;若 Data 为指针,再打印 fmt.Printf("%#+v\n", *resp.Data)
  • 测试函数顶部用简短中文注释说明测的是哪条接口、什么场景。

5.4 运行

go test ./services/<包名> -run Test<名称> -v