Fireboom V2.0 更新说明

145 天前
 Fireboom

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

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

构建物优化

构建物位于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 数据源

其主要用途如下:

详情见 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 。

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 、数据源默认无限,此外还具有如下特性:

企业版

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

详情请前往官网 查看

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

结语

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

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

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

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

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

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

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

未来,邀您一起见证!

917 次点击
所在节点    分享创造
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1006819

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX