V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Fireboom
V2EX  ›  分享创造

Fireboom V2.0 更新说明

  •  
  •   Fireboom · 130 天前 · 904 次点击
    这是一个创建于 130 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Fireboom2.0 是一个值得骄傲的作品!其中最亮眼的特性是:多人协作支持极致性能提升

    有内测用户讲,2.0 升级后好像没啥变化,我打趣道:2.0 样子没变,心变了

    存储重构,支持协作

    1.0 版本存储层数据结构不合理,无法用 github 合并,只适用于单人开发,无法多人协作。而对团队而言,多人协作是不可或缺的功能。

    在 2.0 版本中,我们对存储层数据结构进行了全面的重新设计和优化,不仅支持基于 GitHub 的离线协作,而且在架构上支持实时协作。

    引擎重构,性能提升:

    1.0 版本存在性能问题,在表数量接近 300 时,常常内省失败,且构建的“超图”冗余过多,导致fireboom.config.json动辄十几个 G ,不仅编译较慢,而且运行时很消耗内存。

    重构引擎,2.0 的生成文件缩小* 10 倍* ,运行内存缩小 10 倍,静态编译速度提升 5 倍

    这还不够,进一步支持了 OPERATION 增量编译,实现了无感编译!

    体验优化,流畅开发:

    1.0 版本也存在一些开发体验问题,其中最影响体验的是钩子服务与 Fireboom 服务的循环依赖。

    2.0 版本重构了钩子 SDK ,采用心跳上报的方式完美解决了该问题,钩子开发前所未有的流畅。

    新功能和改进

    接下来,我们详细介绍全部更新。

    存储结构变更

    旧版store 目录

    store
    ├── hooks
    │   ├── auth
    │   ├── customize
    │   ├── global
    │   ├── hooks
    │   └── uploads
    ├── list
    │   ├── FbAuthentication
    │   ├── FbDataSource
    │   ├── FbOperation
    │   ├── FbRole
    │   ├── FbSDK
    │   └── FbStorageBucket
    └── object
        ├── global_config.json
        ├── global_operation_config.json
        ├── global_system_config.json
        └── operations
    

    旧版存储有两类问题:

    1 ,list 目录中以 json 数组的方式存储所有数据源、OPERATION ,任意 API 的变更,都会影响整体文件,导致多人协作时,经常冲突

    2 ,相同业务存储过于分散,操作一个对象,要同时操作 N 个文件

    新版store目录

    store
    ├── authentication # 对应 list/FbAuthentication
    │   ├── auth0.json
    ├── config
    │   ├── global.operation.json
    │   └── global.setting.json
    ├── datasource # 对应 list/FbDataSource
    │   ├── main.json
    │   ├── system.json
    ├── operation # 对应 list/FbOperation
    │   ├── xxx.graphql  # 对应 exported/operations 下的 xxx.graphql
    │   ├── xxx.json # 将 hooks/hooks 和 list/FbOperation 的文件合在一起
    ├── role # 对应 list/FbRole
    │   ├── admin.json
    │   └── user.json
    ├── sdk
    │   └── golang-server.json
    └── storage # 对应 list/FbStorageBucket
        └── aliyun.json
    

    新版存储,重新设计了存储结构,完全解决了旧版的两大问题,且具备如下优势:

    • 方便合并:每个文件代表一个对象,例如 OPERATION operation
    • 统一读取:OPERATION 相关的业务都存储在了同一个 json 中
    • 方便管理:将exported/operations目录下.graphql文件移到了 operation 目录,和.json同名

    构建物优化

    构建物位于exported/generated目录,v1.0 版本中fireboom.config.json文件中有很多冗余,动辄十几个 G 。

    新版本将其拆分为了 2 个文件:fireboom.config.jsonfireboom.operations.json,且将冗余存储改为了引用存储,数十倍的减少了文件大小。小的构建物,成倍缩小了运行内存。

    此外,文件的拆分也减少了 GraphQL 对象的转换次数,成倍提升了合成超图的速度。

    增量编译

    1.0 版本任意一次 OPERATION 的编辑都会触发全量的 OPERATION 编译,造成巨大的性能浪费。新版本将全量编译改为了增量编译,极大提升了 OPERATION 的编译速度!

    这取决于项目 OPERATION 的数量,OPEARTION 越多,提升效果越显著!

    Prisma 数据源

    2.0 版本增加了一种特殊数据源:Prisma 数据源,适用于数据库表数量较多的场景。

    prisma 数据源

    其主要用途如下:

    • 虚拟外键:数据库无需建立外键,只在 Pirsma model 中建立,支持同数据库的关联查询
    • 支持视图:在 prisma model 建立视图表,实现视图的查询
    • 精简数据表:简化 prisma model 表或字段,只声明业务需要的表或字段,缩减超图大小,提高性能

    详情见 Prisma 数据源 !

    钩子扩展逻辑

    OPERATION 结合钩子能实现大部分接口,但仍有些接口无法实现,需要自行编写代码支持。

    1.0 版本只支持 GraphQL 钩子和proxy 钩子,2.0 版本新增了function 钩子,且还解决了钩子的循环依赖问题。

    修改钩子代码后,只需重启钩子,对应的数据将自动注册到 Fireboom 服务中。

    该特性,当前只有 golang 钩子支持,nodejs 钩子正在进行中。

    GraphQL 钩子

    GraphQL 钩子注册到 Fireboom 中为一种特殊的 GraphQL 数据源。

    见上图,数据源->statistic

    GraphQL 示例代码

    package customize
    
    import (
    	"custom-go/pkg/plugins"
    	"fmt"
    
    	"log"
    	"time"
    
    	"github.com/graphql-go/graphql"
    )
    
    type Feed struct {
    	ID string `graphql:"id"`
    }
    
    var FeedType = graphql.NewObject(graphql.ObjectConfig{
    	Name: "FeedType",
    	Fields: graphql.Fields{
    		"id": &graphql.Field{
    			Type: graphql.ID,
    		},
    	},
    })
    var RootSubscription = graphql.NewObject(graphql.ObjectConfig{
    	Name: "subscription",
    	Fields: graphql.Fields{
    		"feed": &graphql.Field{
    			Type: FeedType,
    			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
    				return p.Source, nil
    			},
    			Subscribe: func(p graphql.ResolveParams) (interface{}, error) {
    				c := make(chan interface{})
    
    				go func() {
    					var i int
    
    					for {
    						i++
    
    						feed := Feed{ID: fmt.Sprintf("%d", i)}
    
    						select {
    						case <-p.Context.Done():
    							log.Println("[RootSubscription] [Subscribe] subscription canceled")
    							close(c)
    							return
    						default:
    							c <- feed
    						}
    
    						time.Sleep(250 * time.Millisecond)
    
    						if i == 21 {
    							close(c)
    							return
    						}
    					}
    				}()
    
    				return c, nil
    			},
    		},
    	},
    })
    var StatisticsSchema, _ = graphql.NewSchema(graphql.SchemaConfig{
    	Query: graphql.NewObject(graphql.ObjectConfig{
    		Name: "query",
    		Fields: graphql.Fields{
    			"GetMonthlySales": &graphql.Field{
    				Type: graphql.String,
    				Resolve: func(p graphql.ResolveParams) (res interface{}, err error) {
    					_, _, err = plugins.ResolveArgs[any](p)
    					if err != nil {
    						return
    					}
    					return "ok", nil
    				},
    			},
    		},
    	}),
    	Subscription: RootSubscription,
    })
    
    func init() {
    	plugins.RegisterGraphql(&StatisticsSchema)
    }
    
    

    function 钩子

    function 钩子注册到 Fireboom 中为一个 API ,且有出入参定义( json 类型),此外还支持实时查询和权限控制。

    见上图,API 管理->function->login

    function 示例代码

    package function
    
    import (
    	"custom-go/pkg/base"
    	"custom-go/pkg/plugins"
    )
    
    func init() {
    	plugins.RegisterFunction[loginReq, loginRes](login)
    }
    
    type loginReq struct {
    	Username string `json:"username"`
    	Password string `json:"password"`
    	Res      loginRes
    }
    
    type loginRes struct {
    	Msg  string `json:"msg"`
    	Data string `json:"data"`
    }
    
    func login(hook *base.HookRequest, body *base.OperationBody[loginReq, loginRes]) (*base.OperationBody[loginReq, loginRes], error) {
    	body.Response = &base.OperationBodyResponse[loginRes]{Data: loginRes{Msg: "123"}}
    	return body, nil
    }
    
    

    proxy 钩子

    proxy 钩子注册到 Fireboom 中也为一个 API ,和 funciton 的区别是,它没有出入参定义,可以为任意类型,如非结构化数据或 xml 数据,同时不支持实时查询。

    见上图,API 管理-> proxy->test

    proxy 示例代码

    package proxy
    
    import (
    	"custom-go/pkg/base"
    	"custom-go/pkg/plugins"
    	"custom-go/pkg/wgpb"
    	"net/http"
    )
    
    func init() {
    	plugins.RegisterProxyHook(ping)
    }
    
    var conf = &plugins.HookConfig{
    	AuthRequired: true,
    	AuthorizationConfig: &wgpb.OperationAuthorizationConfig{
    		RoleConfig: &wgpb.OperationRoleConfig{
    			RequireMatchAny: []string{"admin", "user"},
    		},
    	},
    	EnableLiveQuery: false,
    }
    
    func ping(hook *base.HttpTransportHookRequest, body *plugins.HttpTransportBody) (*base.ClientResponse, error) {
    	// do something here ...
    	body.Response = &base.ClientResponse{
    		StatusCode: http.StatusOK,
    	}
    	body.Response.OriginBody = []byte("ok")
    	return body.Response, nil
    }
    
    

    推荐优先使用 function ,funciton 满足不了的,再用 proxy 钩子。

    若想使上述 3 个钩子生效,还需要在main.go文件中开启 5-7 行注释,匿名导入钩子。

    package main
    
    import (
    	// 根据需求,开启注释
    	_ "custom-go/customize"
    	_ "custom-go/function"
    	_ "custom-go/proxy"
    	"custom-go/server"
    )
    
    func main() {
    	server.Execute()
    }
    

    fromclaim 指令升级

    1.0 版本@fromClaim指令只支持枚举值,无法注入自定义的数据。

    新版本新增了custom参数,从 User.CustomClaims 中获取数据,实现了任意数据的注入,包括 标量和数组。其入参为jsonPathComponents,填写参数路径即可。

    package authentication
    
    import (
    	"custom-go/pkg/base"
    	"custom-go/pkg/plugins"
    )
    
    func MutatingPostAuthentication(hook *base.AuthenticationHookRequest) (*plugins.AuthenticationResponse, error) {
    	// 定义自定义参数,其中 key1 为字符串,key2 为对象
    	hook.User.CustomClaims = map[string]any{
    		"key1": "sss",
    		"key2": map[string]string{
    			"key3": "sss",
    		},
    	}
    	return &plugins.AuthenticationResponse{User: hook.User, Status: "ok"}, nil
    }
    
    # 将 User.CustomClaims 的 key2.key3 注入到$name 中
    mutation MyQuery($name: String! @fromClaim(name:CUSTOM,custom: {jsonPathComponents: ["key2", "key3"]})) {
      rb_createOneT(data: {name: $name}) {
        id
        name
      }
    }
    

    事务支持

    新增@transaction指令,修饰 mutation OPERATION ,适用于如下场景:

    • 至少有两个及以上的选择集(根字段)
    • 且必须是同一个数据库
    mutation MyQuery @transaction {
      rb_createOneT(data: { name: "22211122"}) {
        id
        name
      }
      rb_createOneRole(data: {code: "a111111", name: "1111"}) {
        code
        name
      }
    } 
    

    SDK 升级策略优化

    稳定更新,避免过度升级

    1.0 版本的每次被删除后,都会从 github 拉取最新模板,导致过度升级。遇到破坏性更新时,钩子会报错。

    因此,在 sdk 的 json 文件中增加了 gitCommitHash字段,记录模板的 github hash 值,保证每次都能拉取指定版本。

      "gitCommitHash": "e7fa762965b03d47057643dda8784ada625b0cee",
    

    此外,还增加了新版本检测功能,展示是否有新版本,并基于 github 的对比功能,实现了新旧版本对比。

    例如:https://github.com/fireboomio/sdk-template_go-server/compare/ab1427e..e7fa762

    强制忽略,允许定制模板

    1.0 版本会对比template/[sdk-name]custom-[x]中的文件更新时间,确定是否覆盖模板文件。若用户在 custom-[x]中修改模板,则每次编译都会被重新覆盖。

    为了支持该特性,我们在custom-[x]中增加了.fbignore文件,语法类似.gitignore。模板生成时将忽略该文件声明的文件或目录,保证开发者修改不会被覆盖。

    例如:如若修改main.go,则:

    # 略
    main.go
    

    环境变量优化

    1.0 版本的系统配置未支持环境变量,如设置->系统,不同环境迁移时,需要手动处理。

    2.0 版本优化了环境变量,通过环境变量可无缝迁移开发环境到生产环境。

    迁移到 V2.0

    兼容性

    1.0 到 2.0 是一个破坏性更新,未来 1.0 不继续维护,但仍可以使用。

    但我实在想不出,继续使用它的理由,不是吗?

    迁移脚本

    如果你已经有基于 1.0 版本项目,不用担心,我们提供了迁移脚本及教程。

    您可以遵循下述仓库的教程操作,建议在开发环境下进行

    https://github.com/fireboomio/fb-migration

    如果有任何问题,我们将为您提供 1 对 1 指导,且免费!

    文档及支持资源

    当前您看到的就是 2.0 的文档。

    2.0 的文档暂未完全更新,但无需担心,只要您认真阅读 新功能和改进,基于 1.0 文档就可以上手 2.0 。

    接下来,我们将逐渐更新 2.0 文档。

    如有任何问题,可前往内测群咨询,前往->

    我们非常欢迎您提出 2.0 的反馈意见,这将是我们持续进步的动力!

    这里有两个 2.0 的示例项目供您参考:

    RoadMap

    除了 新功能和改进外,还有一些我们计划支持的新特性。也希望您 联系我们 提供更多建议。

    实时协作

    当前只支持离线协作,2.0 计划支持实时协作,满足团队协作的需求。

    • 多人协作功能,允许团队成员同时使用和编辑同一个项目
    • 用户可以实时查看其他成员的更改,并进行实时协作和沟通,提高团队的协作效率

    钩子新语言支持

    当前钩子已完全支持 golang ,进一步优化 nodejs ,随后支持 JAVA 、Python 语言!

    API 市场

    上线 API 市场,集成 2 大类 API 。

    • 通用 API:例如支付能力、短信验证码、邮箱发送、敏感词等通用 API
    • 模型 API:集成各种 AI 模型,如 GPT 、辅助编码、图片生成等

    IDE 优化

    优化内置 IDE ,支持各种钩子语言的开发,包括语法提醒和在线调试。

    当前可基于 github codespace 作为替代品,详情见 文档

    AI 辅助

    辅助编程

    基于 IDE 提供 AI 辅助编程能力,其相对于市面上同类工具最大的优势是对 Fireboom 钩子的特殊支持

    API 生成

    用自然语言代替手工勾选生成 OPERATION ,实现 API 的自动生成

    基于声明式语法的 API 生成

    AI Agent

    优化 API 文档,集成 AI Agent ,用自然语言实现 API 的编排

    AI Agent Gateway:通过自然语言使用工具

    商业化

    近日 CEC-IDE 事件在开发者中引起了广泛讨论,内测群也对此展开了更深入的讨论。

    最终落脚点是:

    从大众到企业付费意识极弱,软件繁荣不起来。表面看到的很多国外优秀开源作品,背后是人家的高 GDP 能保证牛奶面包可以让你去用爱发电,国外付费软件也是非常多的,开源只是一种营销手段。

    ——来自群友:7.

    对此,我深表认同!

    Fireboom 作为一个还在萌芽中的技术型初创团队,一方面追求心中的月亮——以开发者为中心,另一方面又不可能离开六便士——产品商业化

    从 2.0 开始,Fireboom 将开始探索商业化。但不用担心,我们将为您提供最慷慨的免费特性,在不影响您正常项目的情况下,提供增值服务。

    当前 Fireboom2.0 有三种版本:社区版、专业版、企业版。

    社区版

    其中社区版适用个人开发者,除了拥有 1.0 所有功能外,有如下不同:

    • API 数量:100
    • 数据源数量:5

    但,别担心!当项目需求超出默认限制后,可随时免费申请扩容。申请后,无限期生效!

    详情填写 申请表单~

    专业版

    专业版适用于创业团队,拥有社区版的全部功能,且 API 、数据源默认无限,此外还具有如下特性:

    • 增量编译
    • Prisma 数据源
    • 实时协作:多人编辑时,实时联动
    • 导入/导出:为项目导出 API 及其数据源依赖,导出插件

    企业版

    企业版适用于企业,拥有专业版的全部功能,此外还具有如下特性:

    • 虚拟外键:Prisma 数据源,支持虚拟外键和模型精简
    • 日志监控
    • 限流熔断
    • 定时备份
    • 集群部署
    • ...

    详情请前往官网 查看

    如果您觉得某些政策不合理,请随时联系我们。我们将会慎重考虑您的建议!

    结语

    结束之际,最想感谢的是 Fireboom 内测群所有种子用户。是你们的使用、反馈、建议让我们走到今天!

    为此,群内所有用户都将免费获得:

    1. 理由扩容 API 和数据源数量至 ,且永久有效 前往申请->

    2. 理由增量编译特权1 年**,前往申请->

    1 和 2 只需申请 1 个,申请 2 的话,自动拥有 1 的权限!

    希望接下来的日子,仍有您的陪伴!

    Fireboom 团队将始终坚持“以开发者为中心”的信念,不断推陈出新,改进和提升 Fireboom 的功能和性能。

    未来,邀您一起见证!

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1253 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 23:35 · PVG 07:35 · LAX 16:35 · JFK 19:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.