Uma função definida pelo usuário (UDF) em JavaScript é um tipo de transformação de mensagem única (SMT, na sigla em inglês). As UDFs oferecem uma maneira flexível de implementar uma lógica de transformação personalizada no Pub/Sub, semelhante a UDFs em JavaScript do BigQuery.
As UDFs aceitam uma única mensagem como entrada, realizam as ações definidas na entrada e retornam o resultado do processo.
As UDFs têm as seguintes propriedades principais:
Código:o código JavaScript que define a lógica de transformação.
Nome da função:o nome da função JavaScript no código fornecido que o Pub/Sub aplica às mensagens.
Criar a função JavaScript
O código da UDF precisa conter uma função com a seguinte assinatura:
/**
* Transforms a Pub/Sub message.
* @return {(Object<string, (string | Object<string, string>)>|* null)} - To
* filter a message, return `null`. To transform a message, return a map with
* the following keys:
* - (required) 'data' : {string}
* - (optional) 'attributes' : {Object<string, string>}
* Returning empty `attributes` will remove all attributes from the message.
*
* @param {(Object<string, (string | Object<string, string>)>} - Pub/Sub
* message. Keys:
* - (required) 'data' : {string}
* - (required) 'attributes' : {Object<string, string>}
*
* @param {Object<string, any>} metadata - Pub/Sub message metadata.
* Keys:
* - (optional) 'message_id' : {string}
* - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format
* - (optional) 'ordering_key': {string}
*/
function <function_name>(message, metadata) {
// Perform custom transformation logic
return message; // to filter a message instead, return `null`
}
Entradas
A função recebe as seguintes entradas:
Argumento
message:um objeto JavaScript que representa a mensagem do Pub/Sub. Ele contém as seguintes propriedades:data: (String, obrigatório) o payload da mensagem.attributes: (Object<String, String>, opcional) um mapa de pares de chave-valor que representam atributos de mensagem.
Argumento
metadata:um objeto JavaScript que contém metadados imutáveis sobre a mensagem do Pub/Sub:message_id: (String, opcional) o ID exclusivo da mensagem.publish_time: (String, opcional) o horário de publicação da mensagem no formato RFC 3339 (AAAA-MM-DDTHH:mm:ssZ).ordering_key: (String, opcional) a chave de ordenação da mensagem, se aplicável.
Saídas
A função precisa retornar um destes valores:
Para transformar uma mensagem, edite o conteúdo de
message.dataemessage.attributese retorne o objetomessagealterado.Para filtrar uma mensagem, retorne
null.
Requisitos de entrada / saída
- Se a UDF transformar o payload da mensagem, a entrada e a saída do payload precisarão ser strings codificadas em UTF-8.
- Se a UDF não transformar o payload da mensagem, ele poderá usar qualquer codificação.
- Os pares de chave-valor de atributo precisam ser strings codificadas em UTF-8.
Como as UDFs transformam uma mensagem
O resultado da execução de uma UDF em uma mensagem pode ser um destes:
A UDF transforma uma mensagem.
A UDF retorna
null.SMTs de tópico: o Pub/Sub retorna sucesso ao editor e inclui um ID de mensagem na resposta para as mensagens filtradas. O Pub/Sub não armazena a mensagem nem a envia para assinantes.
SMTs de assinatura: o Pub/Sub confirma a entrega da mensagem sem enviá-la a um assinante.
A UDF gera um erro.
SMTs de tópico: o Pub/Sub retorna o erro ao editor e não publica nenhuma das mensagens.
SMTs de assinatura: o Pub/Sub confirma negativamente a mensagem.
Criar uma SMT de UDF
As SMTs podem ser configuradas em tópicos ou assinaturas do Pub/Sub.
- As SMTs de tópico são executadas antes que o Pub/Sub armazene a mensagem, e os resultados ficam disponíveis para todos os assinantes.
As SMTs de assinatura são executadas antes que a mensagem seja entregue, e os resultados ficam disponíveis apenas para essa assinatura.
Console
No Google Cloud console, acesse a página Tópicos do Pub/Sub.
Crie um tópico ou uma assinatura.
Para criar um tópico, clique em Criar tópico. A página Criar tópico será aberta.
Para criar uma assinatura:
Clique no nome do tópico em que você quer a assinatura.
Clique em Criar assinatura. A página Adicionar assinatura ao tópico será aberta.
Em Transformações, clique em Adicionar uma transformação.
Em Tipo de transformação, selecione UDF em JavaScript.
No campo Nome da função, insira o nome da função JavaScript que a SMT chama. Exemplo:
redactSSN.Na área de texto, insira o código da UDF. Exemplo:
function redactSSN(message, metadata) { const data = JSON.parse(message.data); delete data['ssn']; message.data = JSON.stringify(data); return message; }O código precisa conter uma função cujo nome corresponda ao campo Nome da função.
Se você não quiser que a SMT seja ativada imediatamente, selecione Desativar transformação. Quando essa opção é selecionada, a SMT é criada com o tópico, mas não é executada em mensagens recebidas. Depois que o tópico é criado, é possível editá-lo para ativar a SMT.
Para criar o tópico ou a assinatura, clique em Criar.
gcloud
Criar um arquivo de definição
Crie um arquivo YAML ou JSON que defina a SMT da UDF.
YAML
- javascriptUdf:
code: { FUNCTION_CODE }
functionName: FUNCTION_NAME
JSON
{
"javascriptUdf": {
"code": {
FUNCTION_CODE
}
"functionName": FUNCTION_NAME
}
}
Substitua:
FUNCTION_CODE: o código Javascript da UDF. O código precisa conter uma função cujo nome corresponda ao campo
functionName. Exemplo:function redactSSN(message, metadata) { const data = JSON.parse(message.data); delete data['ssn']; message.data = JSON.stringify(data); return message; }FUNCTION_NAME: o nome da função JavaScript que a SMT chama. Exemplo:
redactSSN.
Criar um tópico ou uma assinatura
Para criar um tópico, execute o
gcloud pubsub topics create
comando.
gcloud pubsub topics create TOPIC_ID \
--message-transforms-file=TRANSFORMS_FILE
Substitua:
- TOPIC_ID: o ID ou nome do tópico que você quer criar.
- TRANSFORMS_FILE: o caminho para o arquivo de definição.
Para criar uma assinatura, execute o
gcloud pubsub subscriptions create
comando.
gcloud pubsub subscriptions create SUBSCRIPTION_ID \
--topic=projects/PROJECT_ID/topics/TOPIC_ID \
--message-transforms-file=TRANSFORMS_FILE
Substitua:
SUBSCRIPTION_ID: o ID ou nome da assinatura a ser criada.
PROJECT_ID: o ID do projeto que contém o tópico.
TOPIC_ID: o ID do tópico a ser assinado.
TRANSFORMS_FILE: o caminho para o arquivo de definição.
Se quiser, valide e teste a SMT antes de criá-la. Para mais informações, consulte as seguintes páginas:
Limitações
O Pub/Sub aplica limites de recursos às UDFs para garantir operações de transformação eficientes. As limitações incluem:
- No máximo 20 KB de código por UDF
- No máximo 500 ms de tempo de execução por mensagem
- Suporte apenas para incorporados padrão do ECMAScript
- Nenhuma chamada para APIs externas
- Nenhuma importação de bibliotecas externas
Exemplos de UDFs
Confira alguns exemplos de UDFs para publicação e assinatura. Você pode encontrar outros exemplos na biblioteca de UDFs.
Função: converter um número inteiro do dia da semana na string correspondente
Quando você adiciona a UDF a seguir a um tópico ou assinatura, as seguintes mudanças ocorrem durante a publicação ou entrega da mensagem:
O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.
A UDF procura um campo chamado
dayOfWeeke, se o valor desse campo for um número entre 0 e 6, o converte em um dia da semana correspondente, comoMonday. Se o campo não existir ou o número não estiver no intervalo de 0 a 6, o código define o campodayOfWeekcomoUnknown.A UDF serializa o payload modificado de volta na mensagem.
O Pub/Sub transmite a mensagem atualizada para a próxima etapa do pipeline.
function intToString(message, metadata) {
const data = JSON.parse(message.data);
switch(`data["dayOfWeek"]`) {
case 0:
data["dayOfWeek"] = "Sunday";
break;
case 1:
data["dayOfWeek"] = "Monday";
break;
case 2:
data["dayOfWeek"] = "Tuesday";
break;
case 3:
data["dayOfWeek"] = "Wednesday";
break;
case 4:
data["dayOfWeek"] = "Thursday";
break;
case 5:
data["dayOfWeek"] = "Friday";
break;
case 6:
data["dayOfWeek"] = "Saturday";
break;
default:
data["dayOfWeek"] = "Unknown";
}
message.data = JSON.stringify(data);
return message;
}
Função: redigir um número de seguro social
Quando você adiciona a UDF a seguir a um tópico ou assinatura, as seguintes mudanças ocorrem durante a publicação ou entrega da mensagem:
O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.
A UDF remove o campo
ssndo payload da mensagem (se ele existir).A UDF serializa o payload modificado de volta na mensagem.
O Pub/Sub transmite a mensagem atualizada para a próxima etapa do pipeline.
function redactSSN(message, metadata) {
const data = JSON.parse(message.data);
delete data['ssn'];
message.data = JSON.stringify(data);
return message;
}
Função: filtrar e confirmar automaticamente mensagens específicas
Quando você adiciona a UDF a seguir a um tópico ou assinatura, as seguintes mudanças ocorrem durante a publicação ou entrega da mensagem:
O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.
A UDF verifica se o payload contém um campo chamado
region.Se o valor do campo
regionnão forUS, a função retornará nulo, fazendo com que o Pub/Sub filtre a mensagem.Se o valor do campo
regionforUS, o Pub/Sub vai transmitir a mensagem original para a próxima etapa do pipeline.
function filterForUSRegion(message, metadata) {
const data = JSON.parse(message.data);
if (data["region"] !== "US") {
return null;
}
return message;
}
Função: validar o conteúdo da mensagem para garantir que o valor não seja maior que 100
Quando você adiciona a UDF a seguir a um tópico ou assinatura, as seguintes mudanças ocorrem durante a publicação ou entrega da mensagem:
O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.
A UDF verifica se a mensagem contém um campo chamado
amount.Se o valor do campo
amountfor maior que100, a função vai gerar um erro.Se o valor do campo
amountnão for maior que100, a função vai retornar a mensagem original.O Pub/Sub vai marcar a mensagem como com falha ou transmitir a mensagem original para a próxima etapa do pipeline.
function validateAmount(message, metadata) {
const data = JSON.parse(message.data);
if (data["amount"] > 100) {
throw new Error("Amount is invalid");
}
return message;
}
A seguir
Conferir outros exemplos na biblioteca de UDFs