定义 http 接口,以及 struct tag 的一点点经验,想法,求大神教育,菜鸟一同探讨

golang_china · · 3335 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
本人菜鸟,师父让我定义 与前台的 http 接口,我就做了,当然过程中被喷惨了。写写我最后的方法,以及我为什么这么写,欢迎大家探讨。 前提,所有接口 POST,json 方式 1.接口最后定义方式,基本上是大模块上是按照功能划分的,小模块上按照界面上需要的数据定义的。其实对后台来说,最好的方法就是不看界面,提供基本接口,让前台去组合。但是前台说 考虑到流量,手机耗电问题,所以最后无条件的 前台需要什么给什么,不需要的后台帮忙处理掉。这样做的坏处就是,后台代码写的比较乱,因为每个前台需要的界面都要单独一个结构体,命名上也比较难命名(因为后台自己的数据结构跟前台需要的差不多,只是少了个别字段),我现在也不知道好的接口到底应该怎么样定义。求大神狠狠教育一下我。 2.因为是 json,所以接口参数都是 user_id  形式的。前台 json 数据都需要 json.Unmarshal 来转成 map 或 struct的,用 map 和 struct 的选择上 其实就是两个方面考虑,用 map 效率高,用 struct 效率低(因为反射,递归),所以我师父的demo都是map,但是我写了几个接口发现 map 的硬伤 是全部硬编码,key要自己一个一个的写,而且数据 还要自己在转成 UserID模式(golang 语法规则,用 user_id 太low了),实在蛋疼的狠,后来我都写成 struct 的了,这样 struct 对照接口定义好,不用像map那样一个一个对着接口看着写了。这样做的一个问题是,在 golang 中 struct 里面的字母要大写,因为这样才是公有的,不然 json.Unmarshal 转不出来数据, 我第一个解决方案,哈哈哈,修改接口,接口数据全部定义成 UserID 形式,当然被一顿狂骂,我自己查了查 不需要那样做,因为 golang 中 struct 支持 tag,所以就这样写了,我感觉还行,虽然慢了点但是也不差这么一点吧。反正我师父没说我,我觉得这样定义挺好的。 3.接口的故事说完了,下面说说 我用 struct tag 的一点点小经验,踩过的一点点小坑。 首先 struct 的 tag 意义就是 转json的时候可以转成自己想要的格式(因为golang 语法规则,struct 里面共有数据只能大写格式导致的问题),不多说了,懂得都懂。我觉得高深一点的是 tag 的存在保证了json功能的完善。比如 在mongodb 中 数据格式是 bson 的,而且主键是 _id,如何将 struct 里面的ID数据直接插入 mongodb呢?答案是tag type a struct { ID string `bson:"_id"` } 通过这个bson标签,这样 mgo(我用的这个驱动)驱动会去找这个标签,json 就被转成了 {"_id": "uuid"}这样的形式了,就成功的把结构体直接插入数据库了,数据库会把 ID 当成 key _id ,这样主键就可以控制了,tag的作用就体现出来了,·json:"xxx",道理也是一样的,具体用法自己看看吧。(tag 的解释我也是猜测的,我没看专门查过官方文档,平常看的时候也没看到这方面的知识,说错了就教育我吧)。 在我使用 tag 的场景还算稍微有点复杂的,因为一方面我要把前台的 json 数据转到结构体,我又想把这个结构体直接插入数据库,中间 还用了一个 thrift 。当然我今天不想说 thrift的问题,所以抽出来只说说,json,转 struct, struct 转 bson的问题,tag 是可以像下面这样用的。 type aa struct { T int64 `thrift:"Time,1,required" bson:"time"json:"time"` C string `thrift:"Content,2,required" bson:"content"json:"content"` I []string `thrift:"Images,3,required" bson:"images"json:"images"` } 忽略 thrift 标签,可以 json,bson 同时用,这样 前台 传过来的 通过 json 标签转成 struct,存入 mongo 的时候用 bson 标签,这样一个结构体就可以从前台一直用到数据库了。代码美如画。 坑:两个标签之间不要加空格,加一个空格貌似没事,加两个就出问题了,转不出来,而且不报错,对新手来说真的是巨大的坑,具体结论可能也不是很严谨,感兴趣自己研究吧,记住我这种写法就行了,不加空格,肯定是没问题的(错误的写法那么多,记不过来。只要记住一种对的,永远这么写!!)。 PS. 当时因为我的结构体都是定义在 thrift 中的,标签也是 thrift 生成的,当时我就为了美如画,自己傻逼一样的都给多加空格对齐了,当时干扰也比较多,连续定位6个小时,才整明白咋回事,不吃不喝只抽烟,真是疯狂的6个小时,thrift 也不给我报错,go也不给我报错,我就一点一点一点一点的找,终于给我找出来了,我当时的方法就是自己写个demo,当时只写了成员变量,所以没加空格,结果是符合预期的,我又把 thrift 生成的标签 拿到我 demo里面用就不行,我对比了一下发现没任何问题,就是多空格,我就删除了空格试试,好了!我真是日了狗了,第一遇上 加空格还会出问题的。。。 对不起大家,我写的很乱,新手可能也看不懂,不过有相同需求的同学肯定能看懂的,看不懂的就记住 1.struct tag 能控制 json 字符串,自己写两个打印出来看看 2.多个tag 一起用的时候 标签之间别加空格。自己去google。 这都是实际应用产生的需求,进而产生的经验, 我觉得以我的天赋,自学肯定学不到这么深入,所以拿出来给自学的同学看看,尽量看吧,我也没时间整理的那么详细让大家都看懂。不懂得可以回帖,有时间的时候会一一回复的,主要我是想抛砖引玉,让大神教教我怎么定义接口,让菜鸟知道 tag 的用法以及坑,为go社区献上一点绵薄之力,毕竟在这里我获得了很多很多,是时候回馈社区了,大家一起加油

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

3335 次点击  
加入收藏 微博
2 回复  |  直到 2016-02-04 03:38:01
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传