Informações gerais sobre as funções definidas pelo usuário (UDFs)

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.data e message.attributes e retorne o objeto message alterado.

  • 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

  1. No Google Cloud console, acesse a página Tópicos do Pub/Sub.

    Acesse Tópicos

  2. 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:

      1. Clique no nome do tópico em que você quer a assinatura.

      2. Clique em Criar assinatura. A página Adicionar assinatura ao tópico será aberta.

  3. Em Transformações, clique em Adicionar uma transformação.

  4. Em Tipo de transformação, selecione UDF em JavaScript.

  5. No campo Nome da função, insira o nome da função JavaScript que a SMT chama. Exemplo: redactSSN.

  6. 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.

  7. 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.

  8. 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:

  1. O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.

  2. A UDF procura um campo chamado dayOfWeek e, se o valor desse campo for um número entre 0 e 6, o converte em um dia da semana correspondente, como Monday. Se o campo não existir ou o número não estiver no intervalo de 0 a 6, o código define o campo dayOfWeek como Unknown.

  3. A UDF serializa o payload modificado de volta na mensagem.

  4. 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:

  1. O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.

  2. A UDF remove o campo ssn do payload da mensagem (se ele existir).

  3. A UDF serializa o payload modificado de volta na mensagem.

  4. 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:

  1. O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.

  2. A UDF verifica se o payload contém um campo chamado region.

  3. Se o valor do campo region não for US, a função retornará nulo, fazendo com que o Pub/Sub filtre a mensagem.

  4. Se o valor do campo region for US, 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:

  1. O Pub/Sub aplica a função à mensagem. Se a mensagem não tiver um payload JSON, a UDF vai gerar um erro.

  2. A UDF verifica se a mensagem contém um campo chamado amount.

  3. Se o valor do campo amount for maior que 100, a função vai gerar um erro.

  4. Se o valor do campo amount não for maior que 100, a função vai retornar a mensagem original.

  5. 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