sqler sql 转rest api 源码解析(三) rest协议
rest 服务说明
rest 协议主要是将配置文件中的宏暴露为rest 接口,使用了labstack/echo web 框架,同时基于context 模型
进行宏管理对象的共享,同时进行了一些中间件的注册 cors RemoveTrailingSlash gzip Recover
rest 启动
- 中间件注册
e.Pre(middleware.RemoveTrailingSlash())
e.Use(middleware.CORS())
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{Level: 9}))
e.Use(middleware.Recover())
- 路由配置
默认配置,以及指定宏的路由
e.GET("/", routeIndex)
e.Any("/:macro", routeExecMacro, middlewareAuthorize)
- 宏执行路由
包含了一个授权的中间件,同时在这个中间件中传递共享变量(macro)
func middlewareAuthorize(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if strings.HasPrefix(c.Param("macro"), "_") {
return c.JSON(403, map[string]interface{}{
"success": false,
"error": "access not allowed",
})
}
macro := macrosManager.Get(c.Param("macro"))
if macro == nil {
return c.JSON(404, map[string]interface{}{
"success": false,
"error": "resource not found",
})
}
if len(macro.Methods) < 1 {
macro.Methods = []string{c.Request().Method}
}
methodIsAllowed := false
for _, method := range macro.Methods {
method = strings.ToUpper(method)
if c.Request().Method == method {
methodIsAllowed = true
break
}
}
if !methodIsAllowed {
return c.JSON(405, map[string]interface{}{
"success": false,
"error": "method not allowed",
})
}
// for _, endpoint := range macro.Authorizers {
// parts := strings.SplitN(endpoint, " ", 2)
// if len(parts) < 2 {
// return c.JSON(500, map[string]interface{}{
// "success": false,
// "error": fmt.Sprintf("authorizer: %s is invalid", endpoint),
// })
// }
// resp, err := resty.R().SetHeaders(map[string]string{
// "Authorization": c.Request().Header.Get("Authorization"),
// }).Execute(parts[0], parts[1])
// if err != nil {
// return c.JSON(500, map[string]interface{}{
// "success": false,
// "error": err.Error(),
// })
// }
// if resp.StatusCode() >= 400 {
// return c.JSON(resp.StatusCode(), map[string]interface{}{
// "success": false,
// "error": resp.Status(),
// })
// }
// }
// 路由共享变量
c.Set("macro", macro)
return next(c)
}
}
- routeExecMacro
routes.go 解析请求参数,解析宏,返回json 格式数据
// routeExecMacro - execute the requested macro
func routeExecMacro(c echo.Context) error {
// 获取请求参数,转换为支持宏绑定的map 对象
macro := c.Get("macro").(*Macro)
input := make(map[string]interface{})
body := make(map[string]interface{})
c.Bind(&body)
for k := range c.QueryParams() {
input[k] = c.QueryParam(k)
}
for k, v := range body {
input[k] = v
}
headers := c.Request().Header
for k, v := range headers {
input["http_"+strings.Replace(strings.ToLower(k), "-", "_", -1)] = v[0]
}
out, err := macro.Call(input)
if err != nil {
code := errStatusCodeMap[err]
if code < 1 {
code = 500
}
return c.JSON(code, map[string]interface{}{
"success": false,
"error": err.Error(),
"data": out,
})
}
return c.JSON(200, map[string]interface{}{
"success": true,
"data": out,
})
}
参考资料
https://github.com/labstack/echo
https://github.com/alash3al/sqler/blob/master/server_rest.go
https://github.com/alash3al/sqler/blob/master/routes.go
sqler sql 转rest api 源码解析(三) rest协议的更多相关文章
- sqler sql 转rest api 源码解析(一)应用的启动入口
sqler sql 转rest api 的源码还是比较简单的,没有比较复杂的设计,大部分都是基于开源 模块实现的. 说明: 当前的版本为2.0,代码使用go mod 进行包管理,如果本地运行注意gol ...
- sqler sql 转rest api 源码解析(四)macro 的执行
macro 说明 macro 是sqler 的核心,当前的处理流程为授权处理,数据校验,依赖执行(include),聚合处理,数据转换 处理,sql 执行以及sql 参数绑定 授权处理 这个是通过go ...
- sqler sql 转rest api 源码解析(二) resp 协议
resp 协议主要是方便使用redis 客户端进行连接,resp 主要是依赖 tidwall/redcon golang redis 协议包 resp 服务说明 server_resp.go 文件,干 ...
- Mybatis源码解析(三) —— Mapper代理类的生成
Mybatis源码解析(三) -- Mapper代理类的生成 在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...
- Celery 源码解析三: Task 对象的实现
Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...
- ReactiveCocoa源码解析(三) Signal代码的基本实现
上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...
- ReactiveSwift源码解析(三) Signal代码的基本实现
上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...
- React的React.createRef()/forwardRef()源码解析(三)
1.refs三种使用用法 1.字符串 1.1 dom节点上使用 获取真实的dom节点 //使用步骤: 1. <input ref="stringRef" /> 2. t ...
- 第三十四节,目标检测之谷歌Object Detection API源码解析
我们在第三十二节,使用谷歌Object Detection API进行目标检测.训练新的模型(使用VOC 2012数据集)那一节我们介绍了如何使用谷歌Object Detection API进行目标检 ...
随机推荐
- ES6-循环
forEach 方法来遍历数组,不能使用break语句中断循环,也不能使用return语句返回到外层函数 myArray.forEach(function (value) { console.log( ...
- 5.10 C++内存管理操作符重载
参考:http://www.weixueyuan.net/view/6388.html 注意: 内存管理操作符new.new[].delete和delete[]同样也可以进行操作符重载,其重载形式既可 ...
- DevExpress v18.1新版亮点——Analytics Dashboard篇(二)
用户界面套包DevExpress v18.1日前正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Analytics Dashboard v18.1 的新功能,快 ...
- mvc项目中实现备份数据库(sqlserver2005)
功能要求:mvc项目,实现数据库备份(bak文件) 实现步骤:<a id="backupDB" href="javascript:" >数据库备份& ...
- [学习] SpringMVC/JavaEE/JavaSE
浅谈@RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别 几个Map集合的区别 Java多线程
- 50_流程控制函数-case结构
case函数的使用一:switch case 的效果 /* Java中 switch(变量或表达式){ case 常量1:语句1:break: ... default:语句n;break; } MyS ...
- git 清空缓冲区
git rm与git rm --cached 当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用 git rm file_path git commit -m 'delet ...
- Spring Web Flow
Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序.Spring Web Flow是Spring MVC的扩展,它支持开发基于流程的应用程序.它将流程的定义与实现流程行为 ...
- linux 将一个文件分解成多个不同名文件
1.通过c直接实现 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include & ...
- 大数据-01-安装Hadoop
环境 服务器:ubuntu-16.04.3-desktop-amd64.iso 创建hadoop用户 sudo useradd -m hadoop -s /bin/bash 本文中会大量使用到sudo ...