GoToPost 轻松将router转换成postman的json
前文
在刚毕业时,由于没工作成天在家做白日梦,做一做便想到了一个好用的小工具,平常后端在使用postman测试自己的api是否有问题时,会一直复制贴上,久了会造成版面凌乱,且没有一个collection去管理。于是我便想到了,如果我可以用一个小程式去自动生成一个postman可以import的格式的话,那是不是会比较方便呢?
也因此这款小工具诞生了。
这款小工具是采取开源的方式,欢迎大家提出意见,甚至是fork,改成自己想要的版本!
接下来会开始介绍这款小工具的逻辑,其实也很简单啦!就只是运用了regex来做捕捉而已。
(由于这是我第一次尝试制作开源的程式,因此长得很简陋,请大家的眼睛见谅(´゚д゚`) )
github连结
Rudy1021/goToPost (github.com)
安装方式
直接执行下列指令:
curl -sSfL https://raw.githubusercontent.com/Rudy1021/GoToPost/master/install.sh | sh
接着在环境变数里面设定:
alias gtp="$GOPATH/bin/gtp"
该指令须在GOPATH指令底下
使用方式
先cd到router.go的文件夹,接着输入gtp -p 127.0.0.1:8888 collectionName
gtp -t 转换成thunder-client -p 转换成postman
程式码介绍 - regex
首先我们必须要先理解gin中可以使用的route的格式有什么:
- "example/Select"
- "/example/Select"
- group
(就我目前所知)这几种是比较常会使用到的route名称,而我的regex则是会无论他有没有/ 我都会抓,在最后放进json时会再检查一次他前面是否有/ 。
程式码讲解
首先会先搜寻:
g1 := router.Group("api")
这一种类型,也就是上文提到的Group,会使用下列的regex去做捕捉:
(.+)\s:=\s\w+\.Group\(\"(.+)\"\)
由于每个人对于变数的命名不太一样,只有Group是固定的,因此在这里我选择把.Group给直接写出来,这样才能提高准确率。
这里会捕捉前缀(g1)以及Group的名称(api)
捕捉g1的原因是为了在接下来使用regex时,可以在捞到该url时,可以直接植入group的名称。
接下来会先判断group的长度是否!=0 若等于便表示这个route.go并没有使用group这个东西,若有则会继续进行For回圈的程式码。
groupRouter := group[2] reForGroupWithActionsAndName := regexp.MustCompile(group[1] + `\.([A-Z]+)\s*\("([^"]+)",\s*([^)]+)\)`) matchesWithGroup := reForGroupWithActionsAndName.FindAllStringSubmatch(string(content), -1)
groupRouter会取得Group的名称(api)
而reForGroupWithActionsAndName则会取得url的路径
(很抱歉本人的命名很烂😅)
再来会使用For回圈去把matchesWithGroup做遍历
for _, route := range matchesWithGroup { if len(route) == 4 { httpMethods := route[1] apiRoutes := route[2] handler := route[3] if apiRoutes[0:1] != "/" { apiRoutes = "/" + apiRoutes } request := models.RequestOfThunder{} request.Method = httpMethods request.Url = baseUrl + "/" + groupRouter + apiRoutes request.Name = handler request.SortNum = 10000 request.Created = now request.Modified = now request.Headers = []string{} request.Params = []string{} request.Tests = []string{} exportJson.Requests = append(exportJson.Requests, request) } }
(此处以Thunder-client为例)
这个httpMethods是看Http Methods是哪一个(Http Methods就是GET、POST、PUT、DELETE)。
apiRoutes就是这个api的url后面是什么。
handler则是他这个func是哪个package的 Ex:Example.GET 最后会把它当成Name。
其他的就只是单纯固定的值,因为我没有用到,所以我才会用成固定的,如果有需要用到的朋友请修改这里即可。
如果没有Group的话,其实也是执行差不多的程式码:
reForActionsWithName := regexp.MustCompile(`\.([A-Z]+)\s*\("([^"]+)",\s*([^)]+)\)`) matchForActionsWithName := reForActionsWithName.FindAllStringSubmatch(string(content), -1)
这里跟上面一样,会捞api的url,并且在捞完以后使用For回圈将资料放进json里面。
Thunder-client介绍
这是一款我在vs code中看到的一个套件,他比起postman来说比较轻便一些,只是他在上个月底变更了一些条约,导致现在一个collection只能够放30个api,因此这个以后也不会再维护了,大家就当看看就好!
Postman程式码不一样的地方
由于postman对于json的定义比较详细一点,因此这里我就说一下有什么不同的地方:
urlRegex := regexp.MustCompile(`^(https?://)?([^:/]+)(:\d+)?`) urlMatch := urlRegex.FindStringSubmatch(baseUrl) host := "" protocol := "" port := "" if len(urlMatch) == 4 { protocol = urlMatch[1] host = urlMatch[2] port = urlMatch[3] if protocol == "" { protocol = "http://" } if port != "" { port = port[1:] // Remove the leading ":" } } else { fmt.Println("Invalid URL format:", baseUrl) }
由于postman需要http(s)://,另外他的port也是分开的
Ex: http://127.0.0.1:8888
会被postman分开成
protocol=http host=127.0.0.1 port=8888
所以这里需要先将输入的ip转换成postman可以使用的格式。
for _, routes := range matchForActionsWithName { if len(routes) == 4 { httpMethods := routes[1] apiRoutes := routes[2] handler := routes[3] if apiRoutes[0:1] != "/" { apiRoutes = "/" + apiRoutes } fullURL := baseUrl + apiRoutes path := strings.Split((apiRoutes), "/") postmanItem := models.Item{} postmanItem.Name = handler postmanItem.Request.Method = httpMethods postmanItem.Request.Headers = []string{} postmanItem.Response = []string{} postmanItem.Request.Url.Raw = fullURL postmanItem.Request.Url.Protocol = protocol postmanItem.Request.Url.Host = strings.Split(host, ".") postmanItem.Request.Url.Path = path postmanItem.Request.Url.Port = port exportJson.Item = append(exportJson.Item, postmanItem) } }
(上面是postman所需要的其他东西,因为我没有用到,所以我将这些都设定成固定的值)
在转换完成以后,只要在postman或是thunder-client中import,就可以直接使用了!
后记
这是我第一次自己写小工具并且自己写文章,所以文笔有些不好的地方请见谅😓。
这个项目虽然两周前就做完了,但懒病发作的我一直没有动力去写教学推广文章,但想着:这周六就是我生日了,想送给自己一个特别的礼物,便趁着上班时间把文章做完了🤣。
感谢看完这篇文章的各位,未来如果我有好主意也会继续发文章的!