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. java阶段学习目标

    0-1年: <java编程思想> 1-2年: <大话设计模式>http://www.cnblogs.com/zuoxiaolong/p/pattern26.html <重 ...

  2. c#dataGridView 知识

    一.单元格内容的操作 // 取得当前单元格内容 Console.WriteLine(DataGridView1.CurrentCell.Value); // 取得当前单元格的列 Index Conso ...

  3. 18-10-16 IE 快捷键的组合方式

    一般快捷键 F11打开/关闭全屏模式 TAB循环的选择地址栏,刷新键和当前标签页 CTRL+F在当前标签页查询字或短语 CTRL+N为当前标签页打开一个新窗口 CTRL+P打印当前标签页 CTRL+A ...

  4. golang fmt占位符

    golang fmt格式"占位符" golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf. 定义示例类型和变量 type Human stru ...

  5. [转]JavaScript与元素间的抛物线轨迹运动

    在张鑫旭的博客看到这个抛物线的小动画,觉得很感兴趣,转载一下方便研究~ 原文地址:http://www.zhangxinxu.com/wordpress/?p=3855 在页面上添加元素的位移动画,除 ...

  6. 'autocomplete="off"'在Chrome中不起作用解决方案

    1.正确的姿势是: <input type="password" name="password" autocomplete="new-passw ...

  7. SpringBoot Maven项目 Helloworld 测试

    SpringBoot 化繁为简,简化配置 SpringBoot官方:http://projects.spring.io/spring-boot/SpringBoot使用介绍:http://blog.c ...

  8. gl_PointSize偶数像素表现精准,基数会模糊化。

  9. path-control demo js

    THREE.Spline = function(a) { function b(a, b, c, d, e, f, g) { a = 0.5 * (c - a); d = 0.5 * (d - b); ...

  10. mysql设置外键约束开启-关闭

    在MySQL中删除一张表或一条数据的时候,出现 [Err] 1451 -Cannot delete or update a parent row: a foreign key constraint f ...