go web framework gin group api 设计
假如让你来设计group api, 你该怎么设计呢?
group api 和普通api的区别在于前缀不同,如果group api的版本为v1.0 那么相对应的url为/v1.0/xxx, 如果是普通api的话那么api相对应的版本为/xxx
在gin web framework 中设计的原则也是以相对路径来区分。
// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
Handlers HandlersChain #处理函数
basePath string #相对路径
engine *Engine #存在哪个engine上
root bool #基于基树判断是否为root
}
先看gin中group 的添加规则:
router := gin.New()
users := router.Group("/users")
先看gin.New()默认的basePath是什么。
// New returns a new blank Engine instance without any middleware attached.
// By default the configuration is:
// - RedirectTrailingSlash: true
// - RedirectFixedPath: false
// - HandleMethodNotAllowed: false
// - ForwardedByClientIP: true
// - UseRawPath: false
// - UnescapePathValues: true
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/", #默认为“/”
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
AppEngine: defaultAppEngine,
UseRawPath: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJsonPrefix: "while(1);",
}
engine.RouterGroup.engine = engine
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine
}
查看router.Group("/users") 的调用
// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
// For example, all the routes that use a common middleware for authorization could be grouped.
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
return &RouterGroup{
Handlers: group.combineHandlers(handlers),
basePath: group.calculateAbsolutePath(relativePath), #根据relativePath这个参数,计算basePath
engine: group.engine,
}
}
查看group.calculateAbsolutePath(relativePath) 的调用
func (group *RouterGroup) calculateAbsolutePath(relativePath string) string {
return joinPaths(group.basePath, relativePath)
}
再查看joinPaths的实现
func joinPaths(absolutePath, relativePath string) string {
if relativePath == "" { #如果没有relativePath 直接返回absolutePath,默认为“/”
return absolutePath
}
#处理最后的“/”
finalPath := path.Join(absolutePath, relativePath)
appendSlash := lastChar(relativePath) == '/' && lastChar(finalPath) != '/'
if appendSlash {
return finalPath + "/"
}
return finalPath
}
go web framework gin group api 设计的更多相关文章
- go web framework gin 路由表的设计
在上一篇go web framework gin 启动流程分析这一篇文章中,我分析了go gin启动的过程,在这一篇文章中我将继续上面的分析,讨论gin 中路由表是如何设计的? 首先查看engine. ...
- go web framework gin middleware 设计原理
场景:一个middleware可以具体为一个函数,而由前面的gin 路由分析可得,每一个路径都对有一个HandlersChain 与其对应. 那么实际上增加一个middleware的过程,就是将每一个 ...
- go web framework gin 启动流程分析
最主要的package : gin 最主要的struct: Engine Engine 是整个framework的实例,它包含了muxer, middleware, configuration set ...
- Web API设计方法论
英文原文:A Web API Design Methodology 为Web设计.实现和维护API不仅仅是一项挑战:对很多公司来说,这是一项势在必行的任务.本系列将带领读者走过一段旅程,从为API确定 ...
- Web API设计方法论--比较完整的web api 开发过程
为Web设计.实现和维护API不仅仅是一项挑战:对很多公司来说,这是一项势在必行的任务.本系列将带领读者走过一段旅程,从为API确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在Web上维护 ...
- Rest Framework简介 和 RESTful API 设计指南
使用Django Rest Framework之前我们要先知道,它是什么,能干什么用? Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API 为什么要使用Res ...
- GOTO Berlin: Web API设计原则
在邮件列表和讨论区中有很多与REST和Web API相关的讨论,下面仅是我个人对这些问题的一些见解,并没有绝对的真理,InnoQ的首席顾问Oliver Wolf在GOTO Berlin大会上开始自己的 ...
- 我所理解的RESTful Web API [设计篇]
<我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...
- 移动互联网实战--Web Restful API设计和基础架构
前言: 在移动互联网的大潮中, Web Restful API逐渐成为Web Server重要的一个分支. 移动端和服务端的交互, 主流的方式还是通过Http协议的形式来进行. 请求以Get/Post ...
随机推荐
- MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1
最近有太多的同学向我提起MongoDB,想要学习MongoDB,还不知道MongoDB到底是什么鬼,或者说,知道是数据库,知道是文件型数据库,但是不知道怎么来用 那么好,所谓千呼万唤始出来,现在我就拉 ...
- button theme
children:[ButtonTheme.bar( child:ButtonBar( children:[ FlatButton... ], ),), ]
- jQuery 新建函数
jQuery 新建函数 格式一: // 格式一:新建添加函数方法并使用 $.extend({ 'xsk':function () { return 'xsk'; } }); // 调用 $.xsk() ...
- [C++ Primer Plus] 第4章、复合类型(二)课后习题
1.编写一个 c++ 程序,如下述输出示例所示的那样请求并显示信息 : What is your first name? Betty SueWhat is your last name? YeweWh ...
- 剑指offer(30)连续子数组和的最大值
题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...
- IDEA复制某个类的包名路径
在对应的类中右键: 然后看图:
- jquery将表单序列化
在工作中经常要将表单数据通过ajax提交,所以需要将表单序列化为json对象. 已经有大神提供了,以前一直百度,现在决定抄过来收藏一下,方便以后自己用,尊重原创,文章转载自:http://www.cn ...
- angular5 @viewChild @ContentChild ElementRef renderer2
@viewChild 作用一:选择组件内节点 <!--视图 --> <div #mydiv><input></div> // 选择 @ViewChild ...
- Spark数据分析-记录关联问题
1. 问题描述 记录关联问题(Record Linkage):有大量从一个或多个源系统来的记录,其中有些记录可能代表了相同的基础实体. 每个实体有若干个属性,比如姓名.地址.生日.我们需要根据这些属性 ...
- Systemd程序及相关命令
Systemd程序及相关命令 Systemd是一款用于Linux操作系统系统管理和服务管理的工具.它向后兼容SysV init脚本,并且支持许多类似于startup系统服务的功能,比如系统快照(sna ...