Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
entangled-states
Advanced tools
Solução de PubSub & RPC usando WebSocket e node.js para aplicações de baixa e média complexidade
Solução de PubSub & RPC usando WebSocket e node.js para aplicações de baixa e média complexidade
entangled-states é uma biblioteca que facilita o desenvolvimento de aplicações dinâmicas por meio dos padrões publish–subscribe e RPC utilizando o protocolo WebSocket.
O entangled-states pode ser usado para integração de
Com entangled-states você pode:
No padrão publish–subscribe, também conhecido como pub-sub, Publicadores disponibilizam mensagens em Tópicos, os Assinantes podem então assinar/subscrever nestes tópicos e processar as mensagens recebidas.
O padrão RPC, Chamada Remota de Procedimento, acrônimo de Remote Procedure Call em inglês, permite que um Método (Action) do servidor possa ser invocado pelos Clientes.
No entangled-states o repositório de dados é usado para obter os dados para publicação em um tópico e também persistir o versionamento das mensagens.
É um repositório de dados. Existe uma implementação de repositório EM MEMÓRIA que é usado nos exemplos. Na documentação existe exemplos de criação de repositórios usando banco de dados Relacional (SQL) e até MongoDB.
O entangled-states define uma classe genérica para os repositórios, permitindo ao desenvolvedor implementar seu proprio repositório usando qualquer banco de dados que lhe interessa. Um repositório possui a seguinte estrutura:
class Repository<T> {
find(criteria: AnyObject, options: AnyObject): Promise<Array<T>>;
count(criteria: AnyObject, options: AnyObject): Promise<number>;
findOne(criteria: AnyObject, options: AnyObject): Promise<T>;
insert(data: Partial<T>, options: AnyObject): Promise<T>;
update(criteria: AnyObject, data: Partial<T>, options: AnyObject): Promise<number>;
remove(criteria: AnyObject, options: AnyObject): Promise<number>;
}
Os parâmetros comuns aos métodos do repositório são:
Parametro | Descrição |
---|---|
criteria | Os filtros da consulta sendo realizada. Você tem a liberdade de usar qualquer estrutura que funcione com a sua implentação. |
options | Pode ser usado pela sua implementação para passar configurações adicionais para uma query, como por exemplo, no MongoDB pode se passar opções como o upsert. |
O entangled-states disponibiliza uma implementação de repositório em memória ( InMemoryRepository<T>
), que pode ser usado para testes.
Exemplo Typescript/ES6
import { InMemoryRepository } from 'entangled-states';
const DB_USERS = new InMemoryRepository();
DB_USERS.insert(data)
.then((row) => { })
.catch((cause) => { });
// ou
try {
let row = await DB_USERS.insert(data);
} catch (cause) {
}
Exemplo ES5
var InMemoryRepository = require("entangled-states").InMemoryRepository;
const DB_USERS = new InMemoryRepository();
DB_USERS.insert(data)
.then(function(row) { })
.catch(function(cause) { });
Como em outros sistemas pub-sub, os tópicos do entangled-states são os canais para transmitir mensagens de produtores para consumidores. O Tópico é o filtro de conteúdo que um cliente pode ter interesse em receber.
Existem dois tipos de tópicos LIVRES e COM IDENTIFICADOR.
O responsável pela criação dos tópicos, bem como a geração do seu conteúdo são os Publicadores.
Um Publicador é uma funcionalidade que permite disponibilizar o conteúdo de um Tópico. O Publicador utiliza um ou mais repositórios para consultar os dados que serão publicados.
Para criar um novo tópico, basta configura-lo usando o método create
da classe Publishers
, conforme.:
import { Publishers } from 'entangled-states';
// Tópico livre
Publishers.create({
topic: 'listagemDeAlgo',
query: {
repository: meuRepository
}
});
// Tópicos com identificador (detalheDeItem#ID)
Publishers.create({
topic: 'detalheDeItem',
idRequired: true,
query: {
repository: meuRepository,
params: {
id: '$id'
}
}
});
// Tópicos com identificador usado para listar dados de uma categoria
Publishers.create({
topic: 'listagemDeCategoria',
idRequired: true,
query: {
repository: meuRepository,
params: {
idCategoria: '$id'
}
}
});
As configurações de um Publicador disponíveis são:
Parametro | Tipo | Requerido | Descrição |
---|---|---|---|
topic | string | Sim | O nome do tópico que está sendo criado |
query | QueryConfig | Array<QueryConfig> | Sim | A configuração da consulta usada para publicar o conteúdo deste tópico. (ver detalhamento abaixo) |
idRequired | boolean | Não | Informa que este Tópico é COM IDENTIFICADOR |
then | (lastResult: AnyObject) => void | Não | Permite executar alguma outra funcionalidade após o envio da mensagem neste Tópico |
Os dados publicados em um Tópico são provenientes da consulta em um ou mais repositórios. A consulta de um Publicador pode ser configurada usando os parametros abaixo.
Parametro | Tipo | Requerido | Descrição |
---|---|---|---|
repository | Repository<any> | Sim | Repositório que possui os dados desejados nesta consulta |
params | AnyObject | Não | Os parametros de consulta no store. Quando o Tópico é COM IDENTIFICADOR os parametros com valor = $id serão substituidos pelo identificador do tópico. Ex. query:{ idCategoria : '$id' } . |
options | AnyObject | Não | Permite configurar opções adicionais do Repositório usado |
singleResult | boolean | Não | Permite definir se o resultado dessa consulta será um array ou uma entidade única. Se TRUE usará o método findOne do Repositório, se FALSE usará o método find . O valor padrão é FALSE . |
filter | (row: AnyObject, index: number, rows: Array<AnyObject>, prevResults: Array<any>) => boolean | Não | Após consultar os dados, permite realizar um filtro em memória. Não se aplica quando singleResult=true |
forEach | (row: AnyObject, index: number, rows: Array<AnyObject>, prevResults: Array<any>) => void | Não | Após filtrar os registros, permite visitar cada um dos itens. Não se aplica quando singleResult=true |
map | (row: AnyObject, index: number, rows: Array<AnyObject>, prevResults: Array<any>) => any | Não | Permite mapear o resultado para outra estrutura de dados diferente da disponibilizada pelo Repositório |
extract | (rows: Array<AnyObject>, prevResults: Array<any>) => AnyObject | Não | Permite extrair um ÚNICO valor de saída, a partir dos resultado da Query atual e das Queries anteriores. |
Exemplo complexo No exemplo abaixo, é feito a criação de um tópico que entrega diversas informações sobre uma categoria de produtos a partir do ID (Obviamente esse exemplo pode ser substituído por apenas um repositório com os filtros desejados, mas o exemplo é apenas para demonstrar a aplicação de multiplas queries em um tópico).
// Publica detalhamento de uma categoria
Publishers.create({
topic: 'detalhesCategoria',
idRequired: true,
query: [
{ // traz filhos da categoria solicitada
repository: CATEGORIA_REPO,
params: {
categoriaPai: '$id'
},
// filtra categorias ativas
filter: (row, index, rows, prevResults) => {
return row.ativo === true;
}
},
{ // conta produtos na categoria solicitada
repository: CONTA_PRODUTOS_REPO,
singleResult: true,
params: {
idCategoria: '$id'
}
},
{ // detalhes da categoria solicitada
repository: CATEGORIA_REPO,
singleResult: true,
params: {
idCategoria: '$id'
},
extract: (rows, prevResults) => {
let filhos: Array<Categoria> = prevResults[0];
let contaProdutos: ContaProduto = prevResults[1][0]; // [1][0] = prevResult 1, item 0
return {
...rows[0], // singleResult: true
totalProdutos: contaProdutos.total,
filhos: filhos
}
}
}
]
});
A transfência das mensagens entre Cliente e Servidor é feito de forma compactada, usando um algoritmo de Delta Encoding (diff & patch) que garante o transporte apenas da diferença existente entre os dados conhecidos pelo cliente com os novos dados publicados no servidor, diminuindo o consumo de banda e latencia.
Sua aplicação Node.js. No servidor serão criados os publicadores de conteúdo e os métodos de ação. Nele também serão criados os repositórios de acesso aos dados.
Sua aplicação consumidora dos dados disponibilizados pelo servidor. Pode ser uma aplicação WEB, aplicativo Mobile ou até mesmo um outro servidor Node.js. O cliente pode se inscrever (SUBSCRIBER) para receber atualizações em um tópico ou até mesmo executar métodos disponibilizados pelo servidor.
Porque é legal :)
O entangled-states vai te ajudar se:
FAQs
Solução de PubSub & RPC usando WebSocket e node.js para aplicações de baixa e média complexidade
We found that entangled-states demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.