Descripción general de las funciones definidas por el usuario (UDF)

Una función definida por el usuario (UDF) de JavaScript es un tipo de transformación de mensaje único (SMT). Las UDFs proporcionan una forma flexible de implementar lógica de transformación personalizada en Pub/Sub, de forma similar a las UDFs de JavaScript de BigQuery.

Las FDU aceptan un solo mensaje como entrada, realizan las acciones definidas en la entrada y devuelven el resultado del proceso.

Las funciones definidas por el usuario tienen las siguientes propiedades clave:

  • Nombre de la función: nombre de la función de JavaScript del código proporcionado que Pub/Sub aplica a los mensajes.

  • Código: el código de JavaScript que define la lógica de transformación. Este código debe contener una función con la siguiente firma:

    /**
    * 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

  • Argumento message: objeto JavaScript que representa el mensaje de Pub/Sub. Contiene las siguientes propiedades:

    • data: (String, obligatorio) Carga útil del mensaje.

    • attributes: (Object<String, String>, opcional) mapa de pares clave-valor que representa los atributos del mensaje.

  • Argumento metadata: objeto JavaScript que contiene metadatos inmutables sobre el mensaje de Pub/Sub:

    • message_id: (String, opcional) ID único del mensaje.

    • publish_time: (String, opcional) Hora de publicación del mensaje en formato RFC 3339 (AAAA-MM-DDTHH:mm:ssZ).

    • ordering_key: (String, opcional) La clave de ordenación del mensaje, si procede.

Resultados

  • Para transformar un mensaje, edita el contenido de message.data y message.attributes, y devuelve el objeto message modificado.

  • Para filtrar un mensaje, devuelve null.

Cómo transforman los UDFs un mensaje

El resultado de ejecutar una UDF en un mensaje puede ser uno de los siguientes:

  • La UDF transforma un mensaje.

  • La FDU devuelve null.

    • SMTs de temas: Pub/Sub devuelve un mensaje de éxito al editor e incluye un ID de mensaje en la respuesta de los mensajes filtrados. Pub/Sub no almacena el mensaje ni lo envía a ningún suscriptor.

    • SMTs de suscripción: Pub/Sub confirma la entrega del mensaje sin enviarlo a un suscriptor.

  • La FDU genera un error.

    • SMTs de temas: Pub/Sub devuelve el error al editor y no publica ninguno de los mensajes.

    • SMTs de suscripción: Pub/Sub confirma negativamente el mensaje.

Limitaciones

Pub/Sub aplica límites de recursos a las UDFs para asegurar que las operaciones de transformación sean eficientes. Entre las limitaciones se incluyen las siguientes:

  • Un máximo de 20 KB de código por función definida por el usuario
  • Un tiempo de ejecución máximo de 500 ms por mensaje
  • Solo se admiten elementos integrados estándar de ECMAScript
  • No se hacen llamadas a APIs externas
  • No se importan bibliotecas externas

Funciones definidas por el usuario de ejemplo

A continuación, se muestran algunas UDFs de ejemplo para publicar y suscribirse. Puedes encontrar más ejemplos en la biblioteca de funciones definidas por el usuario.

Función: convierte un número entero de un día de la semana en la cadena correspondiente.

Cuando añades la siguiente función definida por el usuario a un tema o una suscripción, se producen los siguientes cambios durante la publicación o la entrega de mensajes:

  1. Pub/Sub aplica la función al mensaje. Si el mensaje no tiene una carga útil JSON, la función definida por el usuario genera un error.

  2. La función definida por el usuario busca un campo llamado dayOfWeek y, si el valor de este campo es un número entre 0 y 6, lo convierte en el día de la semana correspondiente, como Monday. Si el campo no existe o el número no está entre 0 y 6, el código asigna el valor Unknown al campo dayOfWeek.

  3. La UDF serializa la carga útil modificada de nuevo en el mensaje.

  4. Pub/Sub envía el mensaje actualizado al siguiente paso de tu 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;
}

Función: ocultar un número de identificación personal

Cuando añades la siguiente función definida por el usuario a un tema o una suscripción, se producen los siguientes cambios durante la publicación o la entrega de mensajes:

  1. Pub/Sub aplica la función al mensaje. Si el mensaje no tiene una carga útil JSON, la función definida por el usuario genera un error.

  2. La función definida por el usuario elimina el campo ssn de la carga útil del mensaje (si existe).

  3. La UDF serializa la carga útil modificada de nuevo en el mensaje.

  4. Pub/Sub envía el mensaje actualizado al siguiente paso de tu pipeline.

function redactSSN(message, metadata) {
  const data = JSON.parse(message.data);
  delete data['ssn'];
  message.data = JSON.stringify(data);
  return message;
}

Función: filtrar y confirmar automáticamente mensajes específicos

Cuando añades la siguiente función definida por el usuario a un tema o una suscripción, se producen los siguientes cambios durante la publicación o la entrega de mensajes:

  1. Pub/Sub aplica la función al mensaje. Si el mensaje no tiene una carga útil JSON, la función definida por el usuario genera un error.

  2. La función definida por el usuario comprueba si la carga útil contiene un campo llamado region.

  3. Si el valor del campo region no es US, la función devuelve null, lo que provoca que Pub/Sub filtre el mensaje.

  4. Si el valor del campo region es US, Pub/Sub pasa el mensaje original al siguiente paso de tu canalización.

function filterForUSRegion(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["region"] !== "US") {
    return null;
  }
  return message;
}

Función: valida el contenido del mensaje para asegurarse de que el importe no sea superior a 100

Cuando añades la siguiente función definida por el usuario a un tema o una suscripción, se producen los siguientes cambios durante la publicación o la entrega de mensajes:

  1. Pub/Sub aplica la función al mensaje. Si el mensaje no tiene una carga útil JSON, la función definida por el usuario genera un error.

  2. La función definida por el usuario comprueba si el mensaje contiene un campo llamado amount.

  3. Si el valor del campo amount es mayor que 100, la función genera un error.

  4. Si el valor del campo amount no es superior a 100, la función devuelve el mensaje original.

  5. A continuación, Pub/Sub marca el mensaje como fallido o pasa el mensaje original al siguiente paso de tu canalización.

function validateAmount(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["amount"] > 100) {
    throw new Error("Amount is invalid");
  }
  return message;
}

Siguientes pasos