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协议的更多相关文章

  1. sqler sql 转rest api 源码解析(一)应用的启动入口

    sqler sql 转rest api 的源码还是比较简单的,没有比较复杂的设计,大部分都是基于开源 模块实现的. 说明: 当前的版本为2.0,代码使用go mod 进行包管理,如果本地运行注意gol ...

  2. sqler sql 转rest api 源码解析(四)macro 的执行

    macro 说明 macro 是sqler 的核心,当前的处理流程为授权处理,数据校验,依赖执行(include),聚合处理,数据转换 处理,sql 执行以及sql 参数绑定 授权处理 这个是通过go ...

  3. sqler sql 转rest api 源码解析(二) resp 协议

    resp 协议主要是方便使用redis 客户端进行连接,resp 主要是依赖 tidwall/redcon golang redis 协议包 resp 服务说明 server_resp.go 文件,干 ...

  4. Mybatis源码解析(三) —— Mapper代理类的生成

    Mybatis源码解析(三) -- Mapper代理类的生成   在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...

  5. Celery 源码解析三: Task 对象的实现

    Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...

  6. ReactiveCocoa源码解析(三) Signal代码的基本实现

    上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...

  7. ReactiveSwift源码解析(三) Signal代码的基本实现

    上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...

  8. React的React.createRef()/forwardRef()源码解析(三)

    1.refs三种使用用法 1.字符串 1.1 dom节点上使用 获取真实的dom节点 //使用步骤: 1. <input ref="stringRef" /> 2. t ...

  9. 第三十四节,目标检测之谷歌Object Detection API源码解析

    我们在第三十二节,使用谷歌Object Detection API进行目标检测.训练新的模型(使用VOC 2012数据集)那一节我们介绍了如何使用谷歌Object Detection API进行目标检 ...

随机推荐

  1. 数据库-->表操作

    一.MySQL存储引擎 # InnoDB MySql 5.6 版本默认的存储引擎.InnoDB 是一个事务安全的存储引擎,它具备提交.回滚以及崩溃恢复的功能以保护用户数据.InnoDB 的行级别锁定以 ...

  2. 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  3. VSTO:使用C#开发Excel、Word【8】

    office加载项Office开发中使用的第二种模式是加载项模式.本书涵盖了几种Office加载项.其中包括Outlook的VSTO加载项,Excel和Word的COM加载项以及Excel的自动化加载 ...

  4. python笔记3-输出输入、字符串格式化

    输入.输出 python怎么来接收用户输入呢,使用input函数,python2中使用raw_input,接收的是一个字符串,输出呢,第一个程序已经写的使用print,代码入下: 1 2 name=i ...

  5. Java作业五

    1.编程生成10个1~100之间的随机数,并统计每个数出现的概率. 这个博文里面又random的详细解释:https://www.cnblogs.com/ningvsban/p/3590722.htm ...

  6. 2017年3月1日09:45:39 css选择器,session数据取不到

    昨天碰到了一个问题,通过输入指定的url进行登录在服务端将url存在session中但是登陆之后因为页面提交的登录请求是ajax请求,在后端提取session时获取不当之前存的url,老司机说不是同一 ...

  7. 解决 java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L的问题

    <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</a ...

  8. centos安装pip扩展包

    1.安装 epel-release扩展yum源# yum install -y epel-release# yum clean all# yum makecache2.安装setuptools# yu ...

  9. Day17作业及默写

    正则表达式练习 1.匹配一篇英文文章的标题 类似 The Voice Of China ([A-Z][a-z]*)( [A-Z][a-z]*)* 2.匹配一个网址 https://www.baidu. ...

  10. java ip 正则表达式

    private static boolean isBoolIp(String ipAddress) { String ip = "(?:(?:25[0-5]|2[0-4][0-9]|[01] ...