文章摘要
Pennybase是一个轻量级的后端即服务(BaaS)解决方案,类似于Firebase、Supabase和Pocketbase。它用不到1000行的Go代码实现了核心后端功能,仅依赖标准库,无外部依赖。数据以CSV文件存储,支持版本记录,提供REST API、JSON响应、会话认证、RBAC权限管理、实时更新、数据验证和模板渲染。数据存储为追加式,每次更新生成新版本,内存索引加速查询。CSV文件的第一列为记录ID,第二列为版本号,其余为数据字段,通过_schemas.csv定义JSON字段到CSV列的映射。
文章总结
Pennybase 是一个轻量级的后端即服务(BaaS)解决方案,类似于 Firebase、Supabase 或 Pocketbase,但其核心功能仅用不到 1000 行的 Go 代码实现,且仅依赖标准库,没有外部依赖。以下是其主要内容总结:
核心功能
- 基于 CSV 的文件存储:数据以人类可读的 CSV 格式存储,每个记录占一行。数据存储是追加式的,每次更新都会创建记录的新版本,读取时始终使用最新版本。为加快查找和更新速度,Pennybase 在内存中维护了最新版本的索引。
- REST API:提供基于 JSON 响应的 REST API,支持资源的增删改查操作。
- 认证与授权:支持基于会话 cookie 和 Basic Auth 的认证,以及基于角色(RBAC)和所有权的权限控制。
- 实时更新:通过服务器发送事件(SSE)实现实时更新。
- 数据验证:支持对数字、文本和列表的字段进行模式验证。
- 模板渲染:使用 Go 模板引擎渲染 HTML 模板。
数据存储与模式
- CSV 文件结构:CSV 文件的第一列是记录 ID,第二列是版本号,其余列是数据字段。通过
_schemas.csv文件定义 JSON 字段到 CSV 列的映射。 - 用户管理:用户信息存储在
_users.csv文件中,包含用户 ID、版本号、密码哈希和角色列表。用户只能通过手动编辑该文件来添加。 - 权限控制:
_permissions.csv文件定义了资源的访问控制规则,基于角色和所有者进行权限检查。
REST API 端点
- GET /api/{resource}:列出资源中的所有记录,支持排序。
- GET /api/{resource}/{id}:根据 ID 获取单个记录。
- POST /api/{resource}:创建新记录(需要“create”权限)。
- PUT /api/{resource}/{id}:更新现有记录(需要“update”权限)。
- DELETE /api/{resource}/{id}:删除记录(需要“delete”权限)。
- GET /api/events/{resource}:通过 SSE 流式传输资源的实时更新(需要“read”权限)。
认证与会话管理
- 用户可以通过发送包含用户名和密码的 POST 请求到
/api/login来创建会话 cookie,后续请求可使用该 cookie 进行认证。调用/api/logout可注销会话并删除 cookie。
静态资源与模板
- Pennybase 可以从
static目录提供静态资源(如 HTML、CSS、JavaScript 文件),并通过/{filename}URL 访问。 - 支持使用 Go 的
html/template包渲染 HTML 模板,模板中可以访问当前用户、资源存储实例、HTTP 请求等信息。
扩展功能
- 钩子(Hooks):可以通过钩子函数扩展 Pennybase 的功能。钩子在每次资源的创建、更新或删除操作时触发,允许进行额外的验证或修改资源数据。如果钩子返回错误,操作将被中止并返回错误响应。
贡献与许可
- 欢迎贡献代码,但要求代码保持简洁、清晰和正确。主要接受错误修复、测试和示例代码的贡献。
- 代码基于 MIT 许可证分发,允许自由使用、修改和分发。
总结
Pennybase 是一个极简的后端服务框架,适合需要轻量级、无依赖的后端解决方案的场景。它通过 CSV 文件存储数据,提供基本的 REST API、认证、权限控制和实时更新功能,同时支持静态资源服务和模板渲染。其设计目标是保持代码简洁,易于理解和扩展。
评论总结
主要观点总结:
对项目简洁性的认可
- Octoth0rpe 喜欢该项目的简洁性,并提到类似的后端选项(如pennybase、trailbase、pocketbase)正在涌现,但希望未来能支持PostgreSQL。
引用:- "I like the simplicity of the approach."
- "I do hope one of them eventually implements postgres as an alternative to sqlite at some point though."
- desireco42 认为Manifest.js体现了项目的极简风格,但建议使用JSON、YML或TOML格式。
引用:- "I find Manifest.js really gives me that minimalist feel that you are going for here."
- "I would find it more palatable if format was JSON or YML or ideally TOML right..."
- Octoth0rpe 喜欢该项目的简洁性,并提到类似的后端选项(如pennybase、trailbase、pocketbase)正在涌现,但希望未来能支持PostgreSQL。
对创建新项目的质疑
- miroljub 质疑为何不直接贡献给Pocketbase,认为两者非常相似。
引用:- "I don't understand why create a new project instead of contributing to Pocketbase, which looks very similar."
- CharlesW 认为Pocketbase已经是“穷人的BaaS”,并质疑为何不使用SQLite而选择CSV格式。
引用:- "Pocketbase is already the poor man's BaaS."
- "The choice to not use a database when two near-perfect tiny candidates exist, and furthermore to choose the notorious CSV format for storing data, is absolutely mystifying."
- miroljub 质疑为何不直接贡献给Pocketbase,认为两者非常相似。
对后端需求的讨论
- TekMol 提出Chrome的File System Access API可能使后端不再必要,用户数据可以直接存储在设备上。
引用:- "Do we still need a back-end, now that Chrome supports the File System Access API on both desktop and mobile?"
- "This way, users do not have to put their data into the cloud. It all stays on their own device."
- TiredOfLife 建议使用成熟的框架如Laravel、Rails、Django或Spring。
引用:- "Or use something that has been used in production for decades like Laravel, Rails, Django or even Spring."
- TekMol 提出Chrome的File System Access API可能使后端不再必要,用户数据可以直接存储在设备上。
对数据存储格式的争议
- pavlov 建议使用JSON而不是CSV,认为JSON更易于解析且不易产生歧义。
引用:- "Why CSV instead of newline-separated JSON arrays?"
- "Ambiguity in your storage format isn’t good in the long run… JSON lines can be trivially parsed anywhere without a second thought."
- jasonthorsness 认为CSV易于调试,但不如SQLite抗崩溃。
引用:- "CSV database is interesting; probably the most trivially-debuggable a database can possibly be."
- "CSV is not very resistant corruption if host crashes midway through a write."
- pavlov 建议使用JSON而不是CSV,认为JSON更易于解析且不易产生歧义。
对项目定位和名称的批评
- ivanjermakov 认为“Back End-as-a-Service”的标题令人困惑,建议遵循原始项目描述。
引用:- "Back End-as-a-Service in the title is confusing. Consider adhering to the original project description."
- riigess 认为该项目更像是大学生的作业,并建议改进。
引用:- "Calling this a Poor Man’s backend isn’t even the wrong name for it. Admittedly, this is what I’d expect from a Sophomore in University."
- "Would love to help you improve this, but we’d have to understand the problem we’re trying to solve better."
- ivanjermakov 认为“Back End-as-a-Service”的标题令人困惑,建议遵循原始项目描述。
对项目未来发展的担忧
- MattDaEskimo 担心“廉价”替代品最终会提高成本,即使是开源项目也可能转向闭源。
引用:- "Start cheap, gather market, then crank the costs after lock-in."
- "Even 'open-source' is abused. First everything is open-source, and then reasons come out for why premium services will be closed source."
- MattDaEskimo 担心“廉价”替代品最终会提高成本,即使是开源项目也可能转向闭源。
其他建议和替代方案
- jonstaab 建议使用nostr,让用户支付数据库费用,并享受丰富的内容类型和社交图。
引用:- "Alternatively, you could use nostr, have your users pay for the database, and get access to rich content types, an existing social graph, and application interoperability."
- steveharman 建议自托管Convex。
引用:- "Self host Convex https://convex.dev ?"
- jonstaab 建议使用nostr,让用户支付数据库费用,并享受丰富的内容类型和社交图。
总结:
评论中对项目的简洁性表示认可,但也对其创建的必要性、数据存储格式(CSV vs JSON/SQLite)、项目定位和未来发展提出了质疑和担忧。同时,评论者还提供了多种替代方案和改进建议。