Links

V2.0更新说明

引言

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示例代码
custom-go/customize/statistic.go
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示例代码
custom-go/function/login.go
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示例代码
custom-go/proxy/test.go
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行注释,匿名导入钩子。
custom-go/main.go
1
package main
2
3
import (
4
// 根据需求,开启注释
5
_ "custom-go/customize"
6
_ "custom-go/function"
7
_ "custom-go/proxy"
8
"custom-go/server"
9
)
10
11
func main() {
12
server.Execute()
13
}

fromclaim指令升级

1.0版本@fromClaim指令只支持枚举值,无法注入自定义的数据。
新版本新增了custom参数,从User.CustomClaims中获取数据,实现了任意数据的注入,包括 标量和数组。其入参为jsonPathComponents,填写参数路径即可。
custom-go/authentication/mutatingPostAuthentication.go
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的对比功能,实现了新旧版本对比。

强制忽略,允许定制模板

1.0版本会对比template/[sdk-name]custom-[x]中的文件更新时间,确定是否覆盖模板文件。若用户在custom-[x]中修改模板,则每次编译都会被重新覆盖。
为了支持该特性,我们在custom-[x]中增加了.fbignore文件,语法类似.gitignore。模板生成时将忽略该文件声明的文件或目录,保证开发者修改不会被覆盖。
例如:如若修改main.go,则:
custom-go/.fbignore
# 略
main.go

环境变量优化

1.0版本的系统配置未支持环境变量,如设置->系统,不同环境迁移时,需要手动处理。
2.0版本优化了环境变量,通过环境变量可无缝迁移开发环境到生产环境。

迁移到V2.0

兼容性

1.0到2.0是一个破坏性更新,未来1.0不继续维护,但仍可以使用。
但我实在想不出,继续使用它的理由,不是吗?

迁移脚本

如果你已经有基于1.0版本项目,不用担心,我们提供了迁移脚本及教程。
您可以遵循下述仓库的教程操作,建议在开发环境下进行
如果有任何问题,我们将为您提供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、数据源默认无限,此外还具有如下特性:
  • 实时协作:多人编辑时,实时联动
  • 导入/导出:为项目导出API及其数据源依赖,导出插件

企业版

企业版适用于企业,拥有专业版的全部功能,此外还具有如下特性:
  • 虚拟外键:Prisma数据源,支持虚拟外键和模型精简
  • 日志监控
  • 限流熔断
  • 定时备份
  • 集群部署
  • ...
详情请前往官网 查看
如果您觉得某些政策不合理,请随时联系我们。我们将会慎重考虑您的建议!

结语

结束之际,最想感谢的是Fireboom内测群所有种子用户。是你们的使用、反馈、建议让我们走到今天!
为此,群内所有用户都将免费获得:
  1. 1.
    理由扩容 API和数据源数量至 ,且永久有效 前往申请->
  2. 2.
    理由增量编译特权1年前往申请->
1和2只需申请1个,申请2的话,自动拥有1的权限!
希望接下来的日子,仍有您的陪伴!
Fireboom团队将始终坚持“以开发者为中心”的信念,不断推陈出新,改进和提升Fireboom的功能和性能。
未来,邀您一起见证!