-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【实践】gin 开发 - 学习打卡 #334
Comments
tips:最近准备用gin做一个web项目,为期周期2周,这两天我会把遇到的一些问题列出来,和大家一起交流,同时如果有相同想法的朋友,也可以一起交流 |
@xhochipe 有興趣,請問怎麼參與呢? |
https://github.com/developer-learning/reading-go/tree/master/examples @xhochipe @liyingzhen 我有个建议是,你们可以分别提交 PR (提交到 examples 下面) |
@yangwenmai 好主意,不過 examples 應該是放一些小主題對吧。不是放整個 app 那種? 例如
|
为了可以让大家相互 review ,所以不单独开项目会好一点。 目录结构,你们两个人可以商量一下。(毕竟你们俩要协同开发) |
@yangwenmai OK @xhochipe �你有加入 slack 嗎?微信也可。咱們商量一下。 |
@liyingzhen 微信可以 ,我微信号(xiaohan_ochipe),我分享下我昨晚遇到的一个问题
|
@xhochipe just created a PR #339, you can keep working on it. Thanks. 👍 @yangwenmai Thank you as well. |
4/10: basic file structures @yangwenmai Gin 开发的看板, 無法做操做。 順便打卡一下,剛剛再看這篇 Standard Package Layout。打算用他的方式設計結構。 |
4/11: create user api |
4/13: Commits: ==================== Articles: Don’t just check errors, handle them gracefully Minimise the number of sentinel error values in your program and convert errors to opaque errors by wrapping them with Finally, use |
4/14: Commits: 1 test: test middlewares ===== Articles: |
大家好 我也想参加,能带带小弟我吗? |
@SupremeAndy 我也是邊做邊學,你可以看一下我的 commit。有問題大家可以討論。 |
想参加,可以加入 Slack channel:https://reading-go.slack.com/messages/CHJHB1BMG |
1/14: |
@xhochipe 麻烦你将开发计划放在这个issue 的描述中。比如: 开发计划V0.1
V0.2
V0.3... |
@yangwenmai 好的 |
@SupremeAndy 上面有slack链接,你可以加入 |
在我的业务中,常常遇见场景是业务函数都抽象成 func DoSomething(ctx context.Context, req RequstStuct)(resp ResponseStruct, err error){ 所以我在 gin 外面用 反射进行了一个包括,自动解 POST 请求中的 json 到 req 中,自动把 resp json.Marshal 到 响应中, 大家有什么更有效率的写法么? var (
errType = reflect.TypeOf((*error)(nil)).Elem()
ctxType = reflect.TypeOf((*context.Context)(nil)).Elem()
)
// 检查返回值
// 允许一个参数在上下文后面
// 把上下文传递进去
func WrapHandler(f interface{}) gin.HandlerFunc {
// 检查参数有效性
validateFuncSignature(f)
return wrapHander(f)
}
func wrapHander(f interface{}) gin.HandlerFunc {
return func(c *gin.Context) {
t := reflect.TypeOf(f)
reqv := reflect.New(t.In(1))
// 对 JSON 结构体进行绑定
err := c.ShouldBindJSON(reqv.Interface())
if err != nil && err != io.EOF {
c.JSON(http.StatusOK, gin.H{
"code": http.StatusBadRequest,
"message": fmt.Sprintf("Request Bind Error, Err Is: %s", err.Error()),
"data": nil,
})
return
}
ctx := c.Request.Context()
// 传入 标准 context 而不是 gin.Context
inValues := []reflect.Value{reflect.ValueOf(ctx), reqv.Elem()}
ret := reflect.ValueOf(f).Call(inValues)
WriteResp(c, ret)
}
}
// 验证函数签名
func validateFuncSignature(f interface{}) {
t := reflect.TypeOf(f)
if t.Kind() != reflect.Func {
panic("handdler shound be function type")
}
// 检查参数类型和长度
// context, struct
funcNumIn := t.NumIn()
if funcNumIn != 2 {
panic("handler function require 2 input paramters")
}
// 检查第一个参数是否是实现了上下文接口
// gin 的上下文是一个结构体而并非 interface{}
if !t.In(0).Implements(ctxType) {
panic("handler function first paramter should by type of *gin.Context if you have 2 input parameters")
}
// 检查最后一位是否是结构体
lastParam := t.In(funcNumIn - 1)
if lastParam.Kind() == reflect.Ptr {
lastParam = lastParam.Elem()
}
if lastParam.Kind() != reflect.Struct {
panic("param kind must is struct")
}
// 检查返回值类型和长度, 允许两种格式
// xxx, err
// err
funcNumOut := t.NumOut()
// 检查最后一位是否实现了 error
if !t.Out(funcNumOut - 1).Implements(errType) {
panic("param return type must is error ")
}
} 使用的时候 gin.Post("/xxxxxx", gee.WrapHandler(DoSomething )) |
|
tips:题外话,本人工作一直用py,业务时间看看go相关的资料
建立这个issue的目的很单纯,希望有着相同爱好兴趣的朋友一起加入打卡,为了提高自己技能
每周坚持至少四天,每天保持2小时学习go,有了一定基础,大家可以投票,可以选择投票最高的一些项目来练习,做完一个请其他大佬们有时间或者机会帮忙在代码写法效率等各个方面点评,然后最后可以按照这个项目流程一起写一个pdf文档或者知识分享文档,这样我们有了基础,又有了练习,做项目中有了思考,会提高比较快。同时帮助后面入门着学习.
下面每天打卡记录
The text was updated successfully, but these errors were encountered: