Pennybase - BaaS open source ultraleve baseado em arquivos
(github.com/zserge)- BaaS (Backend-as-a-Service) ultracompacto implementado com menos de 1.000 linhas de código usando apenas a biblioteca padrão do Go
- Fornece funcionalidades centrais de backend semelhantes a Firebase/Supabase/Pocketbase com base em arquivos locais
- Armazenamento de dados baseado em arquivos usando registros versionados em CSV
- REST API que retorna JSON
- Autenticação baseada em cookie de sessão e Basic Auth
- Suporte a RBAC e sistema de permissões baseado em proprietário
- Validação de esquema
- Renderização de templates baseada em templates Go
Como funciona
-
Armazenamento de dados
- Todos os dados são armazenados em arquivos CSV legíveis por humanos, com um registro por linha
- A primeira coluna é fixada como ID do registro e a segunda coluna como número da versão
- O método de armazenamento é append-only: ele não sobrescreve registros existentes e sempre adiciona uma nova linha de versão a cada atualização
- Nas leituras, apenas a versão mais recente de cada registro é usada
- Para consultas e atualizações rápidas, mantém em memória um índice com o offset de arquivo dos registros na versão mais recente para cada recurso
s1,1,_permissions,_id,text,,,^.+$ s2,1,_permissions,_v,number,1,, s3,1,_permissions,resource,text,,,^.+$ s4,1,_permissions,action,text,,,^.+$ s5,1,_permissions,field,text,,,^.*$ s6,1,_permissions,role,text,,,^.*$ s7,1,_users,_id,text,,,^.+$ s8,1,_users,_v,number,1,, s9,1,_users,salt,text,,, s10,1,_users,password,text,,,^.+$ s11,1,_users,roles,list,,, s12,1,todo,_id,text,,,^.+$ s13,1,todo,_v,number,1,, s14,1,todo,description,text,0,0,".+" s15,1,todo,completed,number,0,1,""
-
Gerenciamento de usuários e permissões
- As credenciais de usuário e a lista de papéis (roles) são armazenadas no arquivo
_users.csvadmin,1,salt,5V5R4S...====,"admin" alice,1,salt,PXHQWN...====, - Usa a mesma estrutura CSV dos demais recursos, mas com o nome de coleção
_users - Não é possível criar usuários via API; é necessário editar o arquivo diretamente
- As credenciais de usuário e a lista de papéis (roles) são armazenadas no arquivo
-
Gerenciamento de permissões
- As regras de controle de acesso por recurso são definidas em
_permissions.csvp1,1,todo,read,,*,"Qualquer usuário autenticado pode ler ToDo" p2,1,todo,create,,*,"Qualquer usuário autenticado pode adicionar um novo ToDo" p3,1,todo,update,owner,"admin,editor","admin/editor podem atualizar ToDo" p4,1,todo,delete,owner,"admin,editor","admin/editor podem excluir ToDo" - Cada linha representa uma regra de permissão
- As regras de controle de acesso por recurso são definidas em
REST API
- Fornece automaticamente uma REST API com base nos recursos (coleções) definidos em
_schemas.csv GET /api/{resource}?sort_by={field}: consulta todos os registros do recurso, com opção de ordenaçãoGET /api/{resource}/{id}: consulta um único registro com o ID especificadoPOST /api/{resource}: cria um novo registro, requer permissão "create"PUT /api/{resource}/{id}: modifica um registro existente, requer permissão "update"DELETE /api/{resource}/{id}: exclui um registro específico, requer permissão "delete"GET /api/events/{resource}: assina o stream em tempo real de Server-Sent Events (SSE) do recurso, requer permissão "read"-
Método de autenticação
- A autenticação das requisições da API suporta Basic Auth ou cookie de sessão
- Criação de cookie de sessão:
- Envie uma requisição para
POST /api/logincomusernameepasswordno body - A resposta inclui um cookie de sessão, e as requisições seguintes passam a ser autenticadas automaticamente
- Envie uma requisição para
- Logout:
- Ao chamar
/api/logout, a sessão é invalidada e o cookie é removido
- Ao chamar
Arquivos estáticos e templates
- É possível servir diretamente arquivos estáticos como HTML, CSS e JavaScript localizados no diretório
static- Exemplo: o arquivo
static/index.htmlpode ser acessado emhttp://endereco-do-servidor/index.html
- Exemplo: o arquivo
- Além disso, também há suporte à renderização de templates HTML usando o pacote
html/templatedo Go- Os arquivos de template ficam no diretório
templatese são renderizados automaticamente quando acessados pela URL
- Os arquivos de template ficam no diretório
- Dados e funções disponíveis dentro dos templates
.User: informações do usuário autenticado no momento (ounilse não estiver autenticado).Store: instância de storage do Pennybase (usada para consultar e listar recursos).Request: objeto da requisição HTTP atual.ID: ID do recurso que está sendo acessado (quando aplicável).Authorize: função para verificar permissões de ação sobre um recurso específico
Recurso de hooks
- É possível estender o comportamento com uma única função de hook
- A função de hook é chamada automaticamente em operações de criação (create), modificação (update) e exclusão (delete) de todos os recursos
-
Princípio de funcionamento
- A função de hook opera recebendo os quatro argumentos abaixo:
trigger: tipo de ação (ex.: create, update, delete)resource: nome do recurso alvo da operaçãouser: informações do usuário que executa a requisiçãores: dados do recurso alterado
- É possível fazer validações adicionais ou modificar dados no ponto de hook
- Como no exemplo, ao criar um recurso de mensagem, é possível preencher automaticamente o autor e o horário de criação
- Se a função de hook retornar um erro, a ação é interrompida imediatamente, e uma resposta de erro é enviada ao cliente
- Isso permite implementar diversas lógicas customizadas, como verificações extras de permissão, ajuste automático de dados e disparo de eventos externos
- A função de hook opera recebendo os quatro argumentos abaixo:
Limitações e cuidados
- Todo o gerenciamento de usuários/permissões/esquemas exige edição direta de arquivos CSV
- Não é adequado para grandes volumes de dados, regras de permissão complexas ou ambientes distribuídos de alto desempenho
- Funciona exclusivamente com código padrão de Go, sem bibliotecas externas (voltado para aprendizado/uso simples)
- Licença MIT; o código-fonte e a estrutura podem ser usados livremente
- Contribuições são bem-vindas, mas pede-se manter a simplicidade/clareza do código. A manutenção deve focar mais em correções de bugs do que em adicionar novas funcionalidades
1 comentários
uau...