精华内容
下载资源
问答
  • golang web 框架 gin beego iris 对比.pdf
  • GoFrame Beego Iris Gin 比较版本 v1.15.2 v1.12.3 v12.0.2 v1.6.3 项目类型 开源(国内) 开源(国内) 开源(海外) 开源(海外) 开源协议 MIT Apache-2 BSD-3-Clause MIT 框架类型 模块化框架 Web框架 Web"框架...

    原文地址:https://goframe.org/pages/viewpage.action?pageId=3673375

    由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web"框架"为主。这里稍微打了个引号,因为大部分"框架"从设计和功能定位上来讲,充其量都只能算是一个组件,需要项目使用的话得自己四处再去找找其他的组件,或者自己造轮子。如果用于Web开发,这些"框架"的Web开发能力均已完备,无太大差别,且均是自标准库net/http.Server的二次封装。由于框架众多,这里笔者只选择了几个曾做过技术选型评估、较为熟悉,且目前比较流行和典型的Golang"框架",从适用于业务项目开发框架的角度,做一个简单的横向比较,以便大家在项目框架选型时做个参考。

    评估指标

    指标

    说明

    基本介绍来源各自官网。
    模块化设计是否支持模块化插拔设计、模块之间低耦合设计,是否可以独立使用其中某部分组件。
    模块完善度框架提供的功能模块是否丰富。模块能否能覆盖日常普遍的开发需求。
    使用易用性易用性不仅仅是值框架好不好用,更多是团队能否在低成本下快速接入,长期来看能否低成本维护。
    文档完善性参考官网提供的介绍资料,包括但不限于:文档、视频、示例、案例资料。同时,本地中文文档支持也是参考项。
    工程化完备是否能够快速接入项目开发,是否提供项目接入规范、设计模式、开发工具链,文档是否完善、源码是否易读、是否便于长期维护。
    开发模式框架适用的开发模式,或者官方推荐的开发模式。
    工程规范项目接入时的开发规范,如目录规范、设计规范、编码规范、命名规范等。
    社区活跃官方与社区沟通是否便捷,问题是否能够快速解答,BUG是否能够快速响应处理。
    开发工具链项目开发时使用到的CLI开发工具,如初始化项目、交叉编译、代码生成、swagger、热编译能力等等。
    Web: 性能测试

    来源第三方评测 https://github.com/the-benchmarker/web-frameworks 。

    Web: 路由冲突处理存在路由注册冲突时有无良好的解决方案,在业务项目开发中比较常见。
    Web: 域名支持Web路由是否支持域名绑定,甚至多域名的绑定。
    Web: 文件服务Web服务是否提供静态资源的访问能力。
    Web: 优雅重启/关闭Web服务在重启时不会影响请求执行,关闭时会等待正在执行的请求处理完,新请求不再接入。
    ORM框架是否自带ORM组件,ORM组件是业务项目的核心组件。无论是自研还是通过第三方组件引入。
    Session框架是否提供会话管理组件,无论是通用型Session组件,还是仅针对于Web服务的Session组件。
    I18N支持国际化组件支持(常用但非核心组件)。
    配置管理配置管理也是框架需要完备的核心组件能力。
    日志组件日志组件也是框架需要完备的核心组件能力。
    数据校验数据校验也是框架需要完备的核心组件能力。
    缓存管理缓存管理也是框架需要完备的核心组件能力。无论是内存还是Redis,无论是自研还是通过第三方组件引入。
    资源打包支持将依赖的文件资源例如静态资源、配置文件等固定文件编译到可执行文件中。框架组件自动支持资源检索。
    链路跟踪框架是否具备分布式链路跟踪能力,分布式跟踪在微服务架构中是必不可少的能力。
    测试框架框架是否支持单元测试接入,提供单元测试接入规范。无论是使用标准库还是第三方测试框架。
    突出优点比较明显的几点优点。
    突出缺点比较明显的几点缺点。

    横向比较

    • 以下部分对比参数涉及评分的部分,满分总共按照10分为标准。
    • 如果标记为"-"的部分,表示不支持或者需要引入第三方插件支持。
    • 以下特性如果官网提供文档则直接提供文档地址,找不到文档但是笔者知道有就会简单标注。
    • 各个"框架"功能特性实现不同,在文档、功能、易用性上存在较大差异,各位朋友可自行查阅链接。

     

    GoFrame

    Beego

    Iris

    Gin

    比较版本v1.15.2v1.12.3v12.0.2v1.6.3
    项目类型开源(国内)开源(国内)开源(海外)开源(海外)
    开源协议MITApache-2BSD-3-ClauseMIT
    框架类型模块化框架Web框架Web"框架"Web"框架"

    基本介绍

    工程完备、简单易用,模块化、高质量、高性能、企业级开发框架。最简单易用的企业级Go应用开发框架。目前发展最快的Go Web框架。提供完整的MVC功能并且面向未来。一个Go语言写的HTTP Web框架。它提供了Martini风格的API并有更好的性能。
    项目地址

    github.com/gogf/gf

    github.com/beego/beegogithub.com/kataras/irisgithub.com/gin-gonic/gin
    官网地址goframe.orgbeego.meiris-go.comgin-gonic.com

    模块化设计

    ---
    模块完善度10642

    使用易用性

    99910

    文档完善度

    10864
    工程化完备10851
    社区活跃910910
    开发模式模块引入三层架构、MVCMVCMVC-
    工程规范分层设计对象设计项目结构--
    开发工具链gf工具链bee工具链--
    Web: 性能测试10889
    Web: HTTPSHTTPS & TLS支持CustomHttpConfiguration支持
    Web: HTTP2--支持支持
    Web: WebSocketWebSocket服务-
    Web: 分组路由路由注册-分组路由NamespaceGroupingRoutes
    Web: 路由冲突处理--
    Web: 域名支持域名绑定---
    Web: 文件服务静态文件服务静态文件处理ServingStaticFiles
    Web: 多端口/实例多端口监听多实例监听-RunMultipleServiceUsingIris-
    Web: 优雅重启/关闭平滑重启特性热升级GracefulShutdownOrRestartGracefulRestartOrStop
    ORMORM文档ORM文档--
    SessionSessionSession-
    I18N支持I18NI18NLocalization-
    模板引擎模板引擎View设计TemplateRenderingHtmlRendering
    配置管理配置管理参数配置-CustomHttpConfig
    日志组件日志组件Logging--
    数据校验数据校验表单数据验证-CustomValidators
    缓存管理缓存管理Cache--
    资源打包资源管理bee工具bale命令--
    链路跟踪链路跟踪---
    测试框架单元测试-TestingTesting
    突出优点goframe主要以工程化和企业级方向为主,特别是模块化设计和工程化设计思想非常棒。针对业务项目而言,提供了开发规范、项目规范、命名规范、设计模式、开发工具链、丰富的模块、高质量代码和文档,社区活跃。作者也是资深的PHP开发者,PHP转Go的小伙伴会倍感亲切。beego开源的比较早,最早的一款功能比较全面的Golang开发框架,一直在Golang领域有着比较大的影响力,作者谢大多年组织着国内影响力比较大GopherCN活动。beego有着比较丰富的开发模块、开箱即用,提供了基于MVC设计模式的项目结构、开发工具链,主要定位为Web开发,当然也可以用于非Web项目开发。iris主要侧重于Web开发,提供了Web开发的一系列功能组件,基于MVC开发模式。iris这一年发展比较快,从一个Web Server的组件,也慢慢朝着beego的设计方向努力。gin专注于轻量级的Web Server,比较简单,易于理解,路由和中间件设计不错,可以看做替代标准库net/http.Server的路由加强版web server。献给爱造轮子的朋友们。
    突出缺点开源时间较晚,推广过于佛系,目前主要面向国内用户,未推广海外。起步较早,自谢大创业后,近几年发展较慢。非模块化设计,对第三方重量级模块依赖较多。

    号称性能最强,结果平平。非模块化设计。最近两年开始朝beego方向发展,但整体框架能力还不完备,需要加油。

    功能简单易用,既是优点,也是缺点。

    经验分享

    不同的需求场景,存在不同的选择。选择适合的工具,解决适合的问题。

    开源不存在孰好孰坏之分,开源作者能够本着开源精神给大家分享技术成果用以学习和使用,这本身就是一件非常不易并且值得称道的事情。

    最后,笔者在这里跟大家分享一下自己所在团队的情况,以及在Golang技术栈转型过程中所走的弯路,希望能在框架选型这一环节,能给大家作一定参考。

    团队最初痛点

    团队转型Golang技术栈的一些背景。主要几点:

    1. 团队后端最初的主要技术栈为PHP,由于业务发展需要,进行微服务改造。第一版微服务采用了PHP+JsonRpc的通信方式。
    2. 随着项目增多,公司也组件了自己的DevOps团队,底层部署转向了Docker+Kubernetes容器架构,并且引入了Golang技术栈。
    3. 由于一些痛点,通过一段时间对PHPGolang的比较,团队决定快速转型Golang技术栈,主要痛点如下:
      1. PHP项目在业务复杂后、项目中后期的开发和维护成本整体偏高。主要原因还是其过高的灵活性,非结构化的变量设计,参差不齐的开发人员素质。
      2. 上云容器化部署后,PHPDevOps效率太低。复杂的Composer版本管理,超大的Docker镜像大小,都影响着DevOps的效率。相比较而言,Golang效率极其高效。
      3. JsonRpc通信协议设计下,接口的扩展性和灵活性很高,但服务之间很难快速确定接口的输入与输出定义,只能根据文档和示例进行对接和维护。由于代码和文档分离,大部分场景下接口文档维护往往滞后于接口变化。随着服务的不断增加,非结构化的通信协议管理使得服务接口的开发和维护成本进一步提高。
      4. JsonRpc的通信协议本质基于HTTP1.x+Json,执行效率过低,算不上真正的微服务通信协议,很难对接上主流的服务治理框架。相比较基于HTTP2.xgRPC协议有着成熟微服务开发框架和服务治理解决方案。
      5. 业务梳理的考量,PHPGolang技术栈的迁移,其实也是一次技术重构的契机,在技术重构的过程中也重新梳理业务系统设计,偿还技术债务。

    进一步的痛点

    Golang确实足够简单,相比较其他的解释类开发语言,没有过多的语法糖和语言特性,因此团队上手很快,并快速完成了一部分业务系统的技术重构。但随之而来的是更加严重的痛点。主要几点:

    1. 轮子过多:Golang实在太简单了,以至于我们的团队成员爆发了压抑许久的闷骚劲,开发了/封装了许多大大小小的轮子。这些轮子均能满足最基本的功能,例如:日志组件、配置管理、数据结构、缓存管理等等。但是轮子并不是实现一个基础功能的半成品就了事,需要保证功能性、稳定性、扩展性和可维护性,要能结合更多生产实践验证,需要能够长期维护、持续进行迭代改进。否则,就是一堆大小不一的成人玩具。直到现在,我们还在为分散在100多个Golang项目中的数十个成人玩具做大统一的事情痛苦不已。当然,这个问题也跟组织架构和团队管理也有很大关系。
    2. 不成体系:
      1. 我们坚信一个package只做一件事情,并且特地使用单仓库包的形式进行包管理,相当于每个package都是独立维护的git仓库。其实单仓库包package设计并不存在必要性,反而独立的单仓库包提高了组件和框架的维护成本。
      2. 这种单仓库包设计难以形成技术体系,在团队技术管理上,难以形成统一的技术框架。单仓包显得很孤立,而一个技术体系的建立除了需要制定规范和标准,更需要技术框架来准确落地。一个成体系的、统一的技术框架,至少涉及到数十个基础技术组件,不可能完全孤立设计。每一个package的基础功能实现都很简单,但是如何能够统一组织在一起却不是一件简单的事情,这需要团队的技术管理者需要有一定的技术底蕴、格局和前瞻性,而不是和普通开发者那样眼界只能局限于package本身。
      3. 这种孤立的单仓库包设计,对于业务项目的规范化约束不强,每一个组件都可以独立替换,也至于痛点1的问题越发严重(连日志组件都好几套,虽然都满足基本的日志规范设计)。最终,我们最初引以为傲的单仓库包设计,最终变成了一堆散沙。例如,就连需要增加标准化的链路跟踪功能,由于单仓库包过于散乱和不统一,使得推进改进成本极其高昂。
      4. 除了使得技术体系难以建立,技术规范难以准确落地之外,每个组件的易用性也设计得较差。举个简单例子,我们的日志组件、缓存组件、数据库组件、HTTP/gRPC Server组件都需要对接配置管理功能,单仓包需要保证低耦合设计,因此开发者在使用的时候需要先手动读取配置、并转换为目标配置对象、并注入到对应的组件初始化方法中,随后才能将该对象运用到业务逻辑中,若干个业务项目均是重复此步骤。其实goframe在这块的易用性设计就挺不错,每个包当然是独立设计的,在统一的技术框架体系下,再独立提供一个耦合的单例模块将常用的对象进行单例化封装,自动实现配置读取、配置对象转换、配置对象注入及组件对象初始化,开发者仅需要调用一个单例方法即可。而这个常用单例模块,成为了我们技术框架体系的一部分,极大地提高了业务项目的开发和维护效率。
    3. 版本不一致:在业务项目不断增多之后,轮子版本不一致性也越来越明显。什么是版本不一致?举个例子。我们有个轮子叫做httpClient,总共发布了10来个版本;我们总共有100多个Golang项目,几乎每个版本都在使用。我们提交了一个bug fix,却难以让所有项目都能更新。对其他的轮子也是类似的情况,况且我们也有数十个各种轮子,被各个项目独立使用中。

    经过反思总结,总结了以下几点:

    1. 团队需要一个统一的技术框架,而不是东拼西凑的一堆单仓库包。
    2. 我们只需要维护一个框架的版本,而不是维护数十个单仓库包的版本。
    3. 框架的组件必须模块化、低耦合设计,保证内部组件也可以独立引用。
    4. 核心组件严格禁止单仓库包设计,并且必须由框架统一维护。

    最终的抉择

    走过这么多弯路之后,我们决心建立一套成体系的Golang开发框架。除了要求团队能够快速学习,维护成本低,并且我们最主要的诉求,是核心组件不能是半成品,框架必须是上过大规模生产验证的,稳定和成熟的。随着,我们重新对行业中流行的技术框架做了技术评估,包括上面说的那些框架。原本的初衷是想将内部的各个轮子统一做一个成体系的框架,在开源项目中找一些有价值的参考。

    后来找到了goframe,仔细评估和学习了框架设计,发现框架设计思想和我们的经验总结如出一则!

    这里不得不提一件尴尬的事情。其实最开始转Golang之前(2019年中旬)也做过一些调研,那时goframe版本还不高,并且我们负责评估的团队成员有一种先入为主的思想,看到模块和文档这么多,感觉应该挺复杂,性能应该不高,于是没怎么看就PASS。后来选择一些看起来简单的开源轮子自己做了些二次封装。

    这次经过一段时间的仔细调研和源码学习,得出一个结论,goframe框架的框架架构、模块化和工程化设计思想非常棒,执行效率很高,模块不仅丰富,而且质量之高,令人惊叹至极!相比较我们之前写的那些半成品轮子,简直就是小巫见大巫。团队踩了一年多的坑,才发现团队确实需要一个统一的技术框架而不是一堆不成体系的轮子,其实人家早已给了一条明光大道,并且一直在前面默默努力。

    经过团队内部的调研和讨论,我们决定使用goframe逐步重构我们的业务项目。由于goframe是模块化设计的,因此我们也可以对一些模块做必要的替换。重构过程比较顺利,基础技术框架的重构并不会对业务逻辑造成什么影响,反而通过goframe的工程化思想和很棒的开发工具链,在统一技术框架后,极大地提高了项目的开发和维护效率,使得团队可以专心于业务开发,部门也陆续有了更多的产出。目前我们已经有大部门业务项目专向了goframe。平台每日流量千万级别。

    最后,感谢开源作者们的默默贡献!我们也在努力推动团队秉着来源社区,回馈社区的思想,未来也会更多参与社区贡献。

     

     

    展开全文
  • 2019 Go 三款主流框架 —— Gin Beego Iris 选型对比

    万次阅读 多人点赞 2019-10-11 13:39:31
    1. 常见框架 1.1 框架排名 Gin 31k [Lite] Beego 22k Iris 16k Echo 15k [Lite] Revel 11k Martini 10k [×] buffalo 5k [Lite] 1.2 框架特性 GinGin 是一个用 Go (Golang) 编写的 web 框架。...

    1. 常见框架

    1.1 框架排名

    • Gin 31k [Lite]
    • Beego 22k
    • Iris 16k
    • Echo 15k [Lite]
    • Revel 11k
    • Martini 10k [×]
    • buffalo 5k [Lite]

    1.2 框架特性

    Gin:

    Gin 是一个用 Go (Golang) 编写的 web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。 如果你是性能和高效的追求者, 你会爱上 Gin.

    快速:基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。

    支持中间件:传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。

    Crash 处理:Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!

    JSON 验证:Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。

    路由组:更好地组织路由。是否需要授权,不同的 API 版本…… 此外,这些组可以无限制地嵌套而不会降低性能。

    错误管理:Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。

    内置渲染:Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。

    可扩展性:新建一个中间件非常简单,去查看示例代码吧。

    文档链接 | 文档详细度:低

    Beego:

    bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建、热编译、开发、测试、和部署。

    简单化:RESTful 支持、MVC 模型,可以使用 bee 工具快速地开发应用,包括监控代码修改进行热编译、自动化测试代码以及自动化打包部署。

    智能化:支持智能路由、智能监控,可以监控 QPS、内存消耗、CPU 使用,以及 goroutine 的运行状况,让您的线上应用尽在掌握。

    模块化:beego 内置了强大的模块,包括 Session、缓存操作、日志记录、配置解析、性能监控、上下文操作、ORM 模块、请求模拟等强大的模块,足以支撑你任何的应用。

    高性能:beego 采用了 Go 原生的 http 包来处理请求,goroutine 的并发效率足以应付大流量的 Web 应用和 API 应用,目前已经应用于大量高并发的产品中。

    文档链接 | 文档详细度:高

    Iris:

    • 专注于高性能
    • 简单流畅的API
    • 高扩展性
    • 强大的路由和中间件生态系统
      • 使用iris独特的表达主义路径解释器构建RESTful API
      • 动态路径参数化或通配符路由与静态路由不冲突
      • 使用重定向选项从URL中删除尾部斜杠
      • 使用虚拟主机和子域名变得容易
      • 分组API和静态或甚至动态子域名
      • net / http和negroni-like处理程序通过iris.FromStd兼容
      • 针对任意Http请求错误 定义处理函数
      • 支持事务和回滚
      • 支持响应缓存
      • 使用简单的函数嵌入资源并与go-bindata 保持兼容
      • mvc
    • 上下文
      • 高度可扩展的试图渲染(目前支持markdown,json,xml,jsonp等等)
      • 正文绑定器和发送HTTP响应的便捷功能
      • 限制请求正文
      • 提供静态资源或嵌入式资产
      • 本地化i18N
      • 压缩(Gzip是内置的)
    • 身份验证
      • Basic Authentication
      • OAuth, OAuth2 (支持27个以上的热门网站)
      • JWT *服务器
      • 通过TLS提供服务时,自动安装和提供来自https://letsencrypt.org的证书
      • 默认为关闭状态
      • 在关闭,错误或中断事件时注册
      • 连接多个服务器,完全兼容 net/http#Server
    • 视图系统.支持五种模板引擎 完全兼容 html/template
    • Websocket库,其API类似于socket.io [如果你愿意,你仍然可以使用你最喜欢的]
    • 热重启
    • Typescript集成 + Web IDE
    • Iris是最具特色的网络框架之一

    文档链接1 文档链接2 wiki | 文档详细度:中

    1.3 性能测试

    • (1):在一定的时间内实现的总调用数,越高越好
    • (2):单次操作耗时(ns/op),越低越好
    • (3):堆内存分配 (B/op), 越低越好
    • (4):每次操作的平均内存分配次数(allocs/op),越低越好
    Benchmark name(1)(2)(3)(4)
    BenchmarkGin_GithubAll300004837500
    BenchmarkAce_GithubAll1000013405913792167
    BenchmarkBear_GithubAll500053444586448943
    BenchmarkBeego_GithubAll300059244474705812
    BenchmarkBone_GithubAll20069573086987848453
    BenchmarkDenco_GithubAll1000015881920224167
    BenchmarkEcho_GithubAll100001547006496203
    BenchmarkGocraftWeb_GithubAll30005708061316561686
    BenchmarkGoji_GithubAll200081803456112334
    BenchmarkGojiv2_GithubAll200012139732747683712
    BenchmarkGoJsonRest_GithubAll20007857961343712737
    BenchmarkGoRestful_GithubAll30052381886896724519
    BenchmarkGorillaMux_GithubAll100102577262118402272
    BenchmarkHttpRouter_GithubAll2000010541413792167
    BenchmarkHttpTreeMux_GithubAll1000031993465856671
    BenchmarkKocha_GithubAll1000020944223304843
    BenchmarkLARS_GithubAll200006256500
    BenchmarkMacaron_GithubAll200011612702041942000
    BenchmarkMartini_GithubAll20099917132265492325
    BenchmarkPat_GithubAll2005590793149956827435
    BenchmarkPossum_GithubAll1000031976884448609
    BenchmarkR2router_GithubAll1000030513477328979
    BenchmarkRivet_GithubAll1000013213416272167
    BenchmarkTango_GithubAll3000552754638261618
    BenchmarkTigerTonic_GithubAll100014394832391045374
    BenchmarkTraffic_GithubAll10011383067265932921848
    BenchmarkVulcan_GithubAll500039425319894609

    2. 应用

    2.1 主机服务

    Gin

    Gin 拥有灵活的开发环境,在运行时可以选择默认的服务器来运行,也可以选择原生的 http.ListenAndServe(":8080", router) 来开启服务,这是因为其本身使用 gin.Default() 创建的 router 对象实现了 Handler 接口,这就以为着其可以选择其他的 HTTP 服务器,如 fvbock/endlessmanners 或者原生的 http.Server 内置的 Shutdown 方法进行服务重启。

    r := gin.Default()
    _ = r.Run()
    // 或者启动原生服务
    manners.ListenAndServe(":8888", r)
    

    BeeGo

    Beego 提供了一个构建工具,有着标准的开发环境规范,可以一键生成工程目录,并在工程目录使用 run 指令可以直接运行项目,并且支持开发模式下的热更新。

    beego.Run()
    

    Iris

    Iris 的主机有多种拓展功能,包括自定义监听服务、主机配置,同时也支持多主机服务。与 Gin 相似的 iris.Router与 net/http/Handler 功能兼容,它可以在任何net/http服务器上进行调整:

    app := iris.New()
    app.Run(iris.Addr(":8080"))
    
    // 或者自定义链接方式与端口号
    l, err := listenerCfg.NewListener("tcp", ":8080")
    if err != nil {
        app.Logger().Fatal(err)
    }
    app.Run(iris.Listener(l))
    
    // 或者启动原生服务
    app.Run(iris.Raw(&http.Server{Addr:":8080"}).ListenAndServe)
    

    2.2 路由

    Gin

    Gin 在路由系统上集成了 HttpRouter 拥有高性能的优势,同时拥有其丰富的功能,包括组合路由、路由验证、CORS 等。

    简单路由:

    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "pong")
    })
    

    分层路由:

    someGroup := router.Group("/someGroup") {
        someGroup.GET("/someGet", getting)
        someGroup.POST("/somePost", posting)
    }
    

    引用来源

    BeeGo

    BeeGo 的路由功能较为丰富,拥有基础路由、固定路由、正则路由、注解路由、namespace等多个功能,其 REST 风格性较强,且有固定的路由层规范。

    简单路由:

    beego.Get("/",func(ctx *context.Context){
         ctx.Output.Body([]byte("hello world"))
    })
    

    固定路由:

    beego.Router("/", &controllers.MainController{})
    beego.Router("/admin", &admin.UserController{})
    beego.Router("/admin/index", &admin.ArticleController{})
    beego.Router("/admin/addpkg", &admin.AddController{})
    

    namespace(分层路由):

    //初始化 namespace
    ns :=
    beego.NewNamespace("/v1",
        beego.NSCond(func(ctx *context.Context) bool {
            if ctx.Input.Domain() == "api.beego.me" {
                return true
            }
            return false
        }),
        beego.NSBefore(auth),
        beego.NSGet("/notallowed", func(ctx *context.Context) {
            ctx.Output.Body([]byte("notAllowed"))
        }),
        beego.NSRouter("/version", &AdminController{}, "get:ShowAPIVersion"),
        beego.NSRouter("/changepassword", &UserController{}),
        beego.NSNamespace("/shop",
            beego.NSBefore(sentry),
            beego.NSGet("/:id", func(ctx *context.Context) {
                ctx.Output.Body([]byte("notAllowed"))
            }),
        ),
        beego.NSNamespace("/cms",
            beego.NSInclude(
                &controllers.MainController{},
                &controllers.CMSController{},
                &controllers.BlockController{},
            ),
        ),
    )
    //注册 namespace
    beego.AddNamespace(ns)
    

    Irisi

    简单路由:

    app.Get("/", func(ctx iris.Context) {
        ctx.HTML("<h1> Hello from /contact </h1>")
    })
    

    分层路由:

    users := app.Party("/users", myAuthMiddlewareHandler)
    // http://localhost:8080/users/42/profile
    users.Get("/{id:int}/profile", userProfileHandler)
    // http://localhost:8080/users/inbox/1
    users.Get("/inbox/{id:int}", userMessageHandler)
    
    // 或者使用嵌套风格
    app.PartyFunc("/users", func(users iris.Party) {
        users.Use(myAuthMiddlewareHandler)
        // http://localhost:8080/users/42/profile
        users.Get("/{id:int}/profile", userProfileHandler)
        // http://localhost:8080/users/messages/1
        users.Get("/inbox/{id:int}", userMessageHandler)
    })
    

    2.3 上下文对象

    在进行路由匹配之后,可以获取到上下文对象,三套框架都对 Context 进行了封装。

    Gin 与 Iris 对 context 的封装均是为其增加了必要的新功能,同时可以返回原生的 http.Request 对象。但 Beego 的 context 模块是对原生的 http.ResponseWriterhttp.Request 对象进行了彻底的封装,将其分为两个部分,分别为 Input 对象与 Output 对象,对应的将常用方法进行封装,并不能调出原生的对象。

    2.4 数据操作

    原生

    在原生开发中,Go 支持解析 JSON 格式的数据处理能力:

    // 解析 JSON
    func Unmarshal(data []byte, v interface{}) error
    
    // 生成 JSON
    func Marshal(v interface{}) ([]byte, error)
    

    如果使用 simplejson 可以简化 JSON 数据的操作:

    js, err := NewJson([]byte(`{
        "test": {
            "array": [1, "2", 3],
            "int": 10,
            "float": 5.150,
            "bignum": 9223372036854775807,
            "string": "simplejson",
            "bool": true
        }
    }`))
    
    arr, _ := js.Get("test").Get("array").Array()
    i, _ := js.Get("test").Get("int").Int()
    ms := js.Get("test").Get("string").MustString()
    

    Gin

    Gin 可以使用 c.ShouldBind方法,可以将参数自动绑定到 struct.该方法是会检查 Url 查询字符串和 POST 的数据,而且会根据 content-type类型,优先匹配JSON或者 XML,之后才是 Form

    接收数据:

    func main() {
        route := gin.Default()
        route.POST("/testing", (c *gin.Context) {
            var person Person // 定义结构体步骤省略
            // 绑定到 person
            if c.ShouldBind(&person) == nil {
                log.Println(person.Name)
                log.Println(person.Address)
                log.Println(person.Birthday)
            }
            c.String(200, "Success")
        })
        route.Run(":8085")
    }
    

    发送数据:

    Gin 输出这 JSON、 XML、 YAML 三种格式非常方便,直接使用对用方法并赋值一个结构体给它就行了。

    同时还可以使用gin.Hgin.H 是一个很巧妙的设计,你可以像javascript定义json一样,直接一层层写键值对,只需要在每一层加上 gin.H即可:

    func main() {
        r := gin.Default()
    
        // gin.H 本质是 map[string]interface{}
        r.GET("/someJSON", func(c *gin.Context) {
            // 会输出头格式为 application/json; charset=UTF-8 的 json 字符串
            c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.GET("/moreJSON", func(c *gin.Context) {
            // 直接使用结构体定义
            var msg struct {
                Name    string `json:"user"`
                Message string
                Number  int
            }
            msg.Name = "Lena"
            msg.Message = "hey"
            msg.Number = 123
            // 会输出  {"user": "Lena", "Message": "hey", "Number": 123}
            c.JSON(http.StatusOK, msg)
        })
    
        r.GET("/someXML", func(c *gin.Context) {
            // 会输出头格式为 text/xml; charset=UTF-8 的 xml 字符串
            c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.GET("/someYAML", func(c *gin.Context) {
            // 会输出头格式为 text/yaml; charset=UTF-8 的 yaml 字符串
            c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.Run(":8080")
    }
    

    引用来源

    Gin 支持返回的数据格式有:HTML, String,JSON, XML, YAML

    BeeGo

    Beego 对与JSON 数据处理则比较复杂,如果接受数据则需要从 context.RequestBody 中取出数据,之后需要使用断言解析数据,实际上,这里的处理方式与原生的是一样的,并未进行功能优化:

    var body map[string]interface{}
    _ = json.Unmarshal(ctx.Input.RequestBody, &body) // 将 json 数据解析到 body 变量中
    username := body["name"].(string) // 使用断言取出单个数据
    

    对于返回一个 json 数据,BeeGo 只是将我们创建的 json 结构对象存放于 context.Data 下的 “json” 字段中,然后调用 context.ServeJSON() 方法时,会去获取 c.Data["json"] 下存放的结构然后将结果转换成 json 的数据格式并发送:

    type User struct {
        Name string `json:"name"`
        Age  int    `json:"age"`
    }
    
    func (c *TestController) TestData() {
    	user := User{
    		Name: "huahua",
    		Age:  18,
    	}
    	c.Data["json"] = user
    	c.ServeJSON()
    }
    

    起始在处理 json 这一步,Beego 只是做了非常简单的替换工作,context.ServeJSON() 的方法调用后,取到我们设置的结构体后调用了:

    func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error
    

    该方法将结构体通过 json.Marshal() 转成了 json 格式,同时又为响应报文添加了相应响应数据格式信息,之后将数据送出。

    此外,BeeGo 支持返回的数据类型由有:JSON、XML、JSONP

    Iris

    Irisi 对处理 JSON 数据的方法进行了封装,同时也拥有验证数据的能力。

    发送数据与前两者无差别,都是先定义结构体,然后底层使用 JSON 库的能力对 JSON 数据进行解析并赋值于创建的对象。

    接收数据:

    func MyHandler(ctx iris.Context) {
        var c Company // 定义结构体省略
        if err := ctx.ReadJSON(&c); err != nil {
            ctx.StatusCode(iris.StatusBadRequest)
            ctx.WriteString(err.Error())
            return
        }
        ctx.Writef("Received: %#+v\n", c)
    }
    

    在对于返回数据的处理上,与 Gin 相似,采用了在 iris.Context.JSON() 方法可以将对象转化为 JSON 数据输出。

    返回数据:

    app.Get("/encode", func(ctx iris.Context) {
        peter := User{
            Firstname: "John",
            Lastname:  "Doe",
            City:      "Neither FBI knows!!!",
            Age:       25,
        }
        //手动设置内容类型: ctx.ContentType("application/javascript")
        ctx.JSON(peter)
    })
    

    引用来源

    此外,Iris 支持返回的数据格式有:binary, text, json, jsonp, xml, markdown

    2.5 模板引擎

    原生

    Go web 能力中包含了模板引擎的支持,可以使用 template 包来进行模板处理,使用类似 ParseParseFileExecute 等方法从文件或者字符串加载模板,然后执行类似下图展示的模板的 merge 操作:

    func handler(w http.ResponseWriter, r *http.Request) {
        t := template.New("some template") // 创建一个模板
        t, _ = t.ParseFiles("tmpl/welcome.html")  // 解析模板文件
        user := GetUser() // 获取当前用户信息
        t.Execute(w, user)  // 执行模板的 merger 操作
    }
    

    原生的模板引擎支持以下的能力:

    • 字段操作:{{.}}

    • 数据遍历: {{with …}}…{{end}} {{range …}}{{end}}

    • 条件处理:if ... else ...

    • 管道符 (基于模板函数)

    • 模板函数

    • 模板变量

    • Must 操作:作用是检测模板是否正确,例如大括号是否匹配,注释是否正确的关闭,变量是否正确的书写。

    • 嵌套模板

    引用来源

    Gin

    Gin 可以通过配置 LoadHTMLGlob() 或者 LoadHTMLFiles() 启用模板渲染,这两个方法挂载与 gin.Defalut() 生成的 router 对象上,用于设置,模板目录 。匹配完成后可以调用 Context.HTML 进行渲染和数据注入。

    同时,与原生不同的是,Gin 可以使用 gin.H() 来向模板注入 json 格式的数据,而不需要创建额外的结构体。

    func main() {
    	router := gin.Default()
    	router.LoadHTMLGlob("templates/*")
    	//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
    	router.GET("/index", func(c *gin.Context) {
    		c.HTML(http.StatusOK, "index.tmpl", gin.H{
    			"title": "Main website",
    		})
    	})
    	router.Run(":8080")
    }
    

    Gin 的模板引擎支持以下能力:

    • 使用自定义的 html 模板渲染
    • 自定义分隔符(模板标签)
    • 继承原生能力

    相比原生,Gin 定义模板的方式是采用创建全局模板对象(LoadHTMLGlob),然后在上下文对象中使用 c.HTML 去直接调用模板路径下的文件渲染模板。而原生则是在路由的上下文对象中创建 Template 对象,然后在上下文对象中渲染 Template 对象完成渲染工作。

    引用来源

    Beego

    beego 的模板处理引擎采用的是 Go 内置的 html/template 包进行处理,而且 beego 的模板处理逻辑是采用了缓存编译方式,也就是所有的模板会在 beego 应用启动的时候全部编译然后缓存在 map 里面,Beego 的模板引擎支持以下能力:

    • 自定义模板目录
    • 自动渲染
    • 自定义模板标签
    • 模板数据:模板中的数据是通过在 Controller 中 this.Data 获取的
    • 自定义模板名称
    • layout 设计、LayoutSection:实际上是模板的组合、嵌套
    • renderform

    引用来源

    Iris

    Iris 自身并没有创建一种直接可用的模板引擎,而是交给用户可以选择任意一种模板引擎,且完全兼容 html/template。

    官方推荐使用 Hero 引擎,可以预编译html模板以获取代码,其拥有以下特性:

    • 高性能.
    • 非常易用.
    • 功能强大,支持模板继承和模板include.
    • 自动编译.

    Hero 文档

    同时可以选用 quicktemplate 引擎,其拥有以下特性:

    1. 非常快。 模板转换为Go代码然后编译
    2. Quicktemplate语法非常接近Go - 在开始使用quicktemplate之前无需学习另一种模板语言
    3. 在模板编译期间几乎所有错误都被捕获,因此生产受模板相关错误的影响较小
    4. 使用方便。有关详细信息,请参阅快速入门和示例
    5. 强大。任意Go代码可以嵌入到模板中并与模板混合。小心这个功能 - 不要从模板中查询数据库and/or外部资源,除非你错过Go中的PHP方 式:)这种功能主要用于任意数据转换
    6. 易于使用的模板继承由Go接口提供支持。 请参阅此示例以获取详细信
    7. 模板被编译为单个二进制文件,因此无需将模板文件复制到服务器

    quicktemplate 文档

    2.6 MVC 架构

    GIn

    Gin 不支持 MVC 架构模式,需要开发者自行实现,具有一定的灵活性。

    Gin MVC 的实现参考

    Beego

    Beego 是标准的 MVC 框架,对 MVC 有着良好的支持,同时提供了 Model 层的 ORM 引擎。

    Iris

    Iris对MVC(模型视图控制器)模式有一流的支持,Iris web框架支持请求数据、模型、持久数据和以最快的速度执行的绑定。其模式流程图如下:

    Iris MVC 的实现参考

    展开全文
  • golang web 框架 gin beego iris 对比

    千次阅读 2019-11-23 19:47:31
    Beego 22k Iris 16k Echo 15k[Lite] Revel 11k Martini 10k[×] buffalo 5k[Lite] 1.2 框架特性 GinGin 是一个用 Go (Golang) 编写的 web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, ...

    1.1 框架排名

    • Gin 31k [Lite]
    • Beego 22k
    • Iris 16k
    • Echo 15k [Lite]
    • Revel 11k
    • Martini 10k [×]
    • buffalo 5k [Lite]

    1.2 框架特性

    Gin:

    Gin 是一个用 Go (Golang) 编写的 web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。 如果你是性能和高效的追求者, 你会爱上 Gin.

    快速:基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。

    支持中间件:传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。

    Crash 处理:Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!

    JSON 验证:Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。

    路由组:更好地组织路由。是否需要授权,不同的 API 版本…… 此外,这些组可以无限制地嵌套而不会降低性能。

    错误管理:Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。

    内置渲染:Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。

    可扩展性:新建一个中间件非常简单,去查看示例代码吧。

    文档链接 | 文档详细度:低

    Beego:

    bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建、热编译、开发、测试、和部署。

    简单化:RESTful 支持、MVC 模型,可以使用 bee 工具快速地开发应用,包括监控代码修改进行热编译、自动化测试代码以及自动化打包部署。

    智能化:支持智能路由、智能监控,可以监控 QPS、内存消耗、CPU 使用,以及 goroutine 的运行状况,让您的线上应用尽在掌握。

    模块化:beego 内置了强大的模块,包括 Session、缓存操作、日志记录、配置解析、性能监控、上下文操作、ORM 模块、请求模拟等强大的模块,足以支撑你任何的应用。

    高性能:beego 采用了 Go 原生的 http 包来处理请求,goroutine 的并发效率足以应付大流量的 Web 应用和 API 应用,目前已经应用于大量高并发的产品中。

    文档链接 | 文档详细度:高

    Iris:

    • 专注于高性能
    • 简单流畅的API
    • 高扩展性
    • 强大的路由和中间件生态系统
      • 使用iris独特的表达主义路径解释器构建RESTful API
      • 动态路径参数化或通配符路由与静态路由不冲突
      • 使用重定向选项从URL中删除尾部斜杠
      • 使用虚拟主机和子域名变得容易
      • 分组API和静态或甚至动态子域名
      • net / http和negroni-like处理程序通过iris.FromStd兼容
      • 针对任意Http请求错误 定义处理函数
      • 支持事务和回滚
      • 支持响应缓存
      • 使用简单的函数嵌入资源并与go-bindata 保持兼容
      • mvc
    • 上下文
      • 高度可扩展的试图渲染(目前支持markdown,json,xml,jsonp等等)
      • 正文绑定器和发送HTTP响应的便捷功能
      • 限制请求正文
      • 提供静态资源或嵌入式资产
      • 本地化i18N
      • 压缩(Gzip是内置的)
    • 身份验证
      • Basic Authentication
      • OAuth, OAuth2 (支持27个以上的热门网站)
      • JWT *服务器
      • 通过TLS提供服务时,自动安装和提供来自https://letsencrypt.org的证书
      • 默认为关闭状态
      • 在关闭,错误或中断事件时注册
      • 连接多个服务器,完全兼容 net/http#Server
    • 视图系统.支持五种模板引擎 完全兼容 html/template
    • Websocket库,其API类似于socket.io [如果你愿意,你仍然可以使用你最喜欢的]
    • 热重启
    • Typescript集成 + Web IDE
    • Iris是最具特色的网络框架之一

    文档链接1 文档链接2 wiki | 文档详细度:中

    1.3 性能测试

    • (1):在一定的时间内实现的总调用数,越高越好
    • (2):单次操作耗时(ns/op),越低越好
    • (3):堆内存分配 (B/op), 越低越好
    • (4):每次操作的平均内存分配次数(allocs/op),越低越好
    Benchmark name(1)(2)(3)(4)
    BenchmarkGin_GithubAll300004837500
    BenchmarkAce_GithubAll1000013405913792167
    BenchmarkBear_GithubAll500053444586448943
    BenchmarkBeego_GithubAll300059244474705812
    BenchmarkBone_GithubAll20069573086987848453
    BenchmarkDenco_GithubAll1000015881920224167
    BenchmarkEcho_GithubAll100001547006496203
    BenchmarkGocraftWeb_GithubAll30005708061316561686
    BenchmarkGoji_GithubAll200081803456112334
    BenchmarkGojiv2_GithubAll200012139732747683712
    BenchmarkGoJsonRest_GithubAll20007857961343712737
    BenchmarkGoRestful_GithubAll30052381886896724519
    BenchmarkGorillaMux_GithubAll100102577262118402272
    BenchmarkHttpRouter_GithubAll2000010541413792167
    BenchmarkHttpTreeMux_GithubAll1000031993465856671
    BenchmarkKocha_GithubAll1000020944223304843
    BenchmarkLARS_GithubAll200006256500
    BenchmarkMacaron_GithubAll200011612702041942000
    BenchmarkMartini_GithubAll20099917132265492325
    BenchmarkPat_GithubAll2005590793149956827435
    BenchmarkPossum_GithubAll1000031976884448609
    BenchmarkR2router_GithubAll1000030513477328979
    BenchmarkRivet_GithubAll1000013213416272167
    BenchmarkTango_GithubAll3000552754638261618
    BenchmarkTigerTonic_GithubAll100014394832391045374
    BenchmarkTraffic_GithubAll10011383067265932921848
    BenchmarkVulcan_GithubAll500039425319894609

    2. 应用

    2.1 主机服务

    Gin

    Gin 拥有灵活的开发环境,在运行时可以选择默认的服务器来运行,也可以选择原生的 http.ListenAndServe(":8080", router) 来开启服务,这是因为其本身使用 gin.Default() 创建的 router 对象实现了 Handler 接口,这就以为着其可以选择其他的 HTTP 服务器,如 fvbock/endless 、 manners 或者原生的 http.Server 内置的 Shutdown 方法进行服务重启。

    r := gin.Default()
    _ = r.Run()
    // 或者启动原生服务
    manners.ListenAndServe(":8888", r)
    

    BeeGo

    Beego 提供了一个构建工具,有着标准的开发环境规范,可以一键生成工程目录,并在工程目录使用 run 指令可以直接运行项目,并且支持开发模式下的热更新。

    beego.Run()
    

    Iris

    Iris 的主机有多种拓展功能,包括自定义监听服务、主机配置,同时也支持多主机服务。与 Gin 相似的 iris.Router与 net/http/Handler 功能兼容,它可以在任何net/http服务器上进行调整:

    app := iris.New()
    app.Run(iris.Addr(":8080"))
    
    // 或者自定义链接方式与端口号
    l, err := listenerCfg.NewListener(“tcp”, “:8080”)
    if err != nil {
    app.Logger().Fatal(err)
    }
    app.Run(iris.Listener(l))
    
    // 或者启动原生服务
    app.Run(iris.Raw(&http.Server{Addr:":8080"}).ListenAndServe)

    2.2 路由

    Gin

    Gin 在路由系统上集成了 HttpRouter 拥有高性能的优势,同时拥有其丰富的功能,包括组合路由、路由验证、CORS 等。

    简单路由:

    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "pong")
    })
    

    分层路由:

    someGroup := router.Group("/someGroup") {
        someGroup.GET("/someGet", getting)
        someGroup.POST("/somePost", posting)
    }
    

    BeeGo

    BeeGo 的路由功能较为丰富,拥有基础路由、固定路由、正则路由、注解路由、namespace等多个功能,其 REST 风格性较强,且有固定的路由层规范。

    简单路由:

    beego.Get("/",func(ctx *context.Context){
         ctx.Output.Body([]byte("hello world"))
    })
    

    固定路由:

    beego.Router("/", &controllers.MainController{})
    beego.Router("/admin", &admin.UserController{})
    beego.Router("/admin/index", &admin.ArticleController{})
    beego.Router("/admin/addpkg", &admin.AddController{})
    

    namespace(分层路由):

    //初始化 namespace
    ns :=
    beego.NewNamespace("/v1",
        beego.NSCond(func(ctx *context.Context) bool {
            if ctx.Input.Domain() == "api.beego.me" {
                return true
            }
            return false
        }),
        beego.NSBefore(auth),
        beego.NSGet("/notallowed", func(ctx *context.Context) {
            ctx.Output.Body([]byte("notAllowed"))
        }),
        beego.NSRouter("/version", &AdminController{}, "get:ShowAPIVersion"),
        beego.NSRouter("/changepassword", &UserController{}),
        beego.NSNamespace("/shop",
            beego.NSBefore(sentry),
            beego.NSGet("/:id", func(ctx *context.Context) {
                ctx.Output.Body([]byte("notAllowed"))
            }),
        ),
        beego.NSNamespace("/cms",
            beego.NSInclude(
                &controllers.MainController{},
                &controllers.CMSController{},
                &controllers.BlockController{},
            ),
        ),
    )
    //注册 namespace
    beego.AddNamespace(ns)
    

    Irisi

    简单路由:

    app.Get("/", func(ctx iris.Context) {
        ctx.HTML("<h1> Hello from /contact </h1>")
    })
    

    分层路由:

    users := app.Party("/users", myAuthMiddlewareHandler)
    // http://localhost:8080/users/42/profile
    users.Get("/{id:int}/profile", userProfileHandler)
    // http://localhost:8080/users/inbox/1
    users.Get("/inbox/{id:int}", userMessageHandler)
    // 或者使用嵌套风格
    app.PartyFunc("/users", func(users iris.Party) {
    users.Use(myAuthMiddlewareHandler)
    // http://localhost:8080/users/42/profile
    users.Get("/{id:int}/profile", userProfileHandler)
    // http://localhost:8080/users/messages/1
    users.Get("/inbox/{id:int}", userMessageHandler)
    })
    

    2.3 上下文对象

    在进行路由匹配之后,可以获取到上下文对象,三套框架都对 Context 进行了封装。

    Gin 与 Iris 对 context 的封装均是为其增加了必要的新功能,同时可以返回原生的 http.Request 对象。但 Beego 的 context 模块是对原生的 http.ResponseWriter 和 http.Request 对象进行了彻底的封装,将其分为两个部分,分别为 Input 对象与 Output 对象,对应的将常用方法进行封装,并不能调出原生的对象。

    2.4 数据操作

    原生

    在原生开发中,Go 支持解析 JSON 格式的数据处理能力:

    // 解析 JSON
    func Unmarshal(data []byte, v interface{}) error
    // 生成 JSON
    func Marshal(v interface{}) ([]byte, error)

    如果使用 simplejson 可以简化 JSON 数据的操作:

    js, err := NewJson([]byte(`{
        "test": {
            "array": [1, "2", 3],
            "int": 10,
            "float": 5.150,
            "bignum": 9223372036854775807,
            "string": "simplejson",
            "bool": true
        }
    }`))
    
    arr, := js.Get(“test”).Get(“array”).Array()
    i, := js.Get(“test”).Get(“int”).Int()
    ms := js.Get(“test”).Get(“string”).MustString()
    

    Gin

    Gin 可以使用 c.ShouldBind方法,可以将参数自动绑定到 struct.该方法是会检查 Url 查询字符串和 POST 的数据,而且会根据 content-type类型,优先匹配JSON或者 XML,之后才是 Form

    接收数据:

    func main() {
        route := gin.Default()
        route.POST("/testing", (c *gin.Context) {
            var person Person // 定义结构体步骤省略
            // 绑定到 person
            if c.ShouldBind(&person) == nil {
                log.Println(person.Name)
                log.Println(person.Address)
                log.Println(person.Birthday)
            }
            c.String(200, "Success")
        })
        route.Run(":8085")
    }
    

    发送数据:

    Gin 输出这 JSON、 XML、 YAML 三种格式非常方便,直接使用对用方法并赋值一个结构体给它就行了。

    同时还可以使用gin.Hgin.H 是一个很巧妙的设计,你可以像javascript定义json一样,直接一层层写键值对,只需要在每一层加上 gin.H即可:

    func main() {
        r := gin.Default()
    
        // gin.H 本质是 map[string]interface{}
        r.GET("/someJSON", func(c *gin.Context) {
            // 会输出头格式为 application/json; charset=UTF-8 的 json 字符串
            c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.GET("/moreJSON", func(c *gin.Context) {
            // 直接使用结构体定义
            var msg struct {
                Name    string `json:"user"`
                Message string
                Number  int
            }
            msg.Name = "Lena"
            msg.Message = "hey"
            msg.Number = 123
            // 会输出  {"user": "Lena", "Message": "hey", "Number": 123}
            c.JSON(http.StatusOK, msg)
        })
    
        r.GET("/someXML", func(c *gin.Context) {
            // 会输出头格式为 text/xml; charset=UTF-8 的 xml 字符串
            c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.GET("/someYAML", func(c *gin.Context) {
            // 会输出头格式为 text/yaml; charset=UTF-8 的 yaml 字符串
            c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
    
        r.Run(":8080")
    }
    

    Gin 支持返回的数据格式有:HTML, String,JSON, XML, YAML

    BeeGo

    Beego 对与JSON 数据处理则比较复杂,如果接受数据则需要从 context.RequestBody 中取出数据,之后需要使用断言解析数据,实际上,这里的处理方式与原生的是一样的,并未进行功能优化:

    var body map[string]interface{}
    _ = json.Unmarshal(ctx.Input.RequestBody, &body) // 将 json 数据解析到 body 变量中
    username := body["name"].(string) // 使用断言取出单个数据
    

    对于返回一个 json 数据,BeeGo 只是将我们创建的 json 结构对象存放于 context.Data 下的 “json” 字段中,然后调用 context.ServeJSON() 方法时,会去获取 c.Data["json"] 下存放的结构然后将结果转换成 json 的数据格式并发送:

    type User struct {
        Name string `json:"name"`
        Age  int    `json:"age"`
    }
    
    func (c *TestController) TestData() {
    user := User{
    Name: “huahua”,
    Age: 18,
    }
    c.Data[“json”] = user
    c.ServeJSON()
    }

    起始在处理 json 这一步,Beego 只是做了非常简单的替换工作,context.ServeJSON() 的方法调用后,取到我们设置的结构体后调用了:

    func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error
    

    该方法将结构体通过 json.Marshal() 转成了 json 格式,同时又为响应报文添加了相应响应数据格式信息,之后将数据送出。

    此外,BeeGo 支持返回的数据类型由有:JSON、XML、JSONP

    Iris

    Irisi 对处理 JSON 数据的方法进行了封装,同时也拥有验证数据的能力。

    发送数据与前两者无差别,都是先定义结构体,然后底层使用 JSON 库的能力对 JSON 数据进行解析并赋值于创建的对象。

    接收数据:

    func MyHandler(ctx iris.Context) {
        var c Company // 定义结构体省略
        if err := ctx.ReadJSON(&c); err != nil {
            ctx.StatusCode(iris.StatusBadRequest)
            ctx.WriteString(err.Error())
            return
        }
        ctx.Writef("Received: %#+v\n", c)
    }
    

    在对于返回数据的处理上,与 Gin 相似,采用了在 iris.Context.JSON() 方法可以将对象转化为 JSON 数据输出。

    返回数据:

    app.Get("/encode", func(ctx iris.Context) {
        peter := User{
            Firstname: "John",
            Lastname:  "Doe",
            City:      "Neither FBI knows!!!",
            Age:       25,
        }
        //手动设置内容类型: ctx.ContentType("application/javascript")
        ctx.JSON(peter)
    })
    

    此外,Iris 支持返回的数据格式有:binary, text, json, jsonp, xml, markdown

    2.5 模板引擎

    原生

    Go web 能力中包含了模板引擎的支持,可以使用 template 包来进行模板处理,使用类似 ParseParseFileExecute 等方法从文件或者字符串加载模板,然后执行类似下图展示的模板的 merge 操作:

    func handler(w http.ResponseWriter, r *http.Request) {
        t := template.New("some template") // 创建一个模板
        t, _ = t.ParseFiles("tmpl/welcome.html")  // 解析模板文件
        user := GetUser() // 获取当前用户信息
        t.Execute(w, user)  // 执行模板的 merger 操作
    }
    

    原生的模板引擎支持以下的能力:

    • 字段操作:{{.}}

    • 数据遍历: {{with …}}…{{end}} {{range …}}{{end}}

    • 条件处理:if ... else ...

    • 管道符 (基于模板函数)

    • 模板函数

    • 模板变量

    • Must 操作:作用是检测模板是否正确,例如大括号是否匹配,注释是否正确的关闭,变量是否正确的书写。

    • 嵌套模板

    Gin

    Gin 可以通过配置 LoadHTMLGlob() 或者 LoadHTMLFiles() 启用模板渲染,这两个方法挂载与 gin.Defalut() 生成的 router 对象上,用于设置,模板目录 。匹配完成后可以调用 Context.HTML 进行渲染和数据注入。

    同时,与原生不同的是,Gin 可以使用 gin.H() 来向模板注入 json 格式的数据,而不需要创建额外的结构体。

    func main() {
    	router := gin.Default()
    	router.LoadHTMLGlob("templates/*")
    	//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
    	router.GET("/index", func(c *gin.Context) {
    		c.HTML(http.StatusOK, "index.tmpl", gin.H{
    			"title": "Main website",
    		})
    	})
    	router.Run(":8080")
    }
    

    Gin 的模板引擎支持以下能力:

    • 使用自定义的 html 模板渲染
    • 自定义分隔符(模板标签)
    • 继承原生能力

    相比原生,Gin 定义模板的方式是采用创建全局模板对象(LoadHTMLGlob),然后在上下文对象中使用 c.HTML 去直接调用模板路径下的文件渲染模板。而原生则是在路由的上下文对象中创建 Template 对象,然后在上下文对象中渲染 Template 对象完成渲染工作。

    Beego

    beego 的模板处理引擎采用的是 Go 内置的 html/template 包进行处理,而且 beego 的模板处理逻辑是采用了缓存编译方式,也就是所有的模板会在 beego 应用启动的时候全部编译然后缓存在 map 里面,Beego 的模板引擎支持以下能力:

    • 自定义模板目录
    • 自动渲染
    • 自定义模板标签
    • 模板数据:模板中的数据是通过在 Controller 中 this.Data 获取的
    • 自定义模板名称
    • layout 设计、LayoutSection:实际上是模板的组合、嵌套
    • renderform

    Iris

    Iris 自身并没有创建一种直接可用的模板引擎,而是交给用户可以选择任意一种模板引擎,且完全兼容 html/template。

    官方推荐使用 Hero 引擎,可以预编译html模板以获取代码,其拥有以下特性:

    • 高性能.
    • 非常易用.
    • 功能强大,支持模板继承和模板include.
    • 自动编译.

    Hero 文档

    同时可以选用 quicktemplate 引擎,其拥有以下特性:

    1. 非常快。 模板转换为Go代码然后编译
    2. Quicktemplate语法非常接近Go - 在开始使用quicktemplate之前无需学习另一种模板语言
    3. 在模板编译期间几乎所有错误都被捕获,因此生产受模板相关错误的影响较小
    4. 使用方便。有关详细信息,请参阅快速入门和示例
    5. 强大。任意Go代码可以嵌入到模板中并与模板混合。小心这个功能 - 不要从模板中查询数据库and/or外部资源,除非你错过Go中的PHP方 式:)这种功能主要用于任意数据转换
    6. 易于使用的模板继承由Go接口提供支持。 请参阅此示例以获取详细信
    7. 模板被编译为单个二进制文件,因此无需将模板文件复制到服务器

    quicktemplate 文档

    2.6 MVC 架构

    GIn

    Gin 不支持 MVC 架构模式,需要开发者自行实现,具有一定的灵活性。

    Gin MVC 的实现参考

    Beego

    Beego 是标准的 MVC 框架,对 MVC 有着良好的支持,同时提供了 Model 层的 ORM 引擎。

    Iris

    Iris对MVC(模型视图控制器)模式有一流的支持,Iris web框架支持请求数据、模型、持久数据和以最快的速度执行的绑定。其模式流程图如下:

    Iris MVC 的实现参考

     

    展开全文
  • 我平时用的iris 用的都是bee run 生产环境建议go build运行 go get github.com/beego/bee Bee is a Fast and Flexible tool for managing your Beego Web Application. Usage: bee command [argum...

    强烈推荐beego中的bee工具 也可仿照其源码写一个
    我平时用的iris 用的都是bee run 生产环境建议go build运行

    其次最近一直在使用gowatching 类似bee工具,bee工具好像是不能脱离gopath
    码云

    go get github.com/beego/bee
    go get github.com/silenceper/gowatch 
    
    gowatch 项目名(常用这种方式在开发环境gowa 按tab键就能补全直接跑)
    
    
    Bee is a Fast and Flexible tool for managing your Beego Web Application.
    
    Usage:
    
        bee command [arguments]
    
    The commands are:
    
        version     show the bee & beego version
        migrate     run database migrations
        api         create an api application base on beego framework
        bale        packs non-Go files to Go source files    
        new         create an application base on beego framework
        run         run the app which can hot compile
        pack        compress an beego project
        fix         Fixes your application by making it compatible with newer versions of Beego
        dlv         Start a debugging session using Delve
        dockerize   Generates a Dockerfile for your Beego application
        generate    Source code generator
        hprose      Creates an RPC application based on Hprose and Beego frameworks
        new         Creates a Beego application
        pack        Compresses a Beego application into a single file
        rs          Run customized scripts
        run         Run the application by starting a local development server
        server      serving static content over HTTP on port
        
    Use bee help [command] for more information about a command.
        
    new 命令
    

    在这里插入图片描述

    展开全文
  • go语言web框架比较:gin vs iris vs echo

    千次阅读 2018-02-26 19:34:15
    前言 由于golang提供了完善的net/http标准库,...从老牌的revel和beego,到新出的gin,和iris等,而且还有一些类似于chi这种router。个人一般小项目,尤其是中间件需要暴露一些http接口的,基本就使用chi即可。本次...
  • protobuf

    2020-07-19 21:11:36
    beego gin iris protobuf 资料链接 github.com/rubyhan1314 net/rpc 服务端 package main import ( "net/rpc" "net/http" "net" "math" ) type MathUtil struct{ } func (m * MathUtil) CalculateCircleArea...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 208
精华内容 83
关键字:

beegoginiris