Ir al contenido principal

Debugging Google Cloud Functions with event signature in Node

In the article Debugging Google Cloud Functions in Node we exposed a first approach of what Google Functions Framework was and how could it be used.

The article was mainly focused on debugging Google Cloud Function with HTTP signature, ie, those functions intended to be triggered by an HTTP request. There are however other ways of triggering the execution of a Google Cloud Function, as for instance Cloud Storage, Firestore or, more commonly, by forwarding a Pub/Sub message.

This article covers how to debug Google Cloud functions intended to be triggered by a Pub/Sub message.

Google Cloud functions with cloud event signature

Let's assume we have a function that must be triggered by a Pub/Sub message. To do that, we need to perform two actions:

  • Properly configuring Google Cloud to specify that our function will be triggered by a given kind of Pub/Sub message. This part is described in the official documentation and it's out of the scope of this article.
  • Coding a Google Cloud function with cloud event signature, what means that the Google Cloud Function entry-point, ie, the function that will be executed when our Google Cloud Function was triggered, needs to declare specific arguments and handle them properly.

As specified in the documentation, the entry-point function must declare a single parameter. In the case of being triggered by a Pub/Sub event, this parameter will be a JSON object similar to this one:

{
   // data contains the Base64 representation
   // of the Pub/Sub message payload,
   // in this case a single string 
   // with value "Hello world!"
   "data": "SGVsbG8gd29ybGQh"
}

Assuming that the entry-point function defines a single parameter called cloudEvent, it would have to get the value of the field cloudEvent.data and then decoding it from base64. Once done, the Pub/Sub message payload would be available to the Google Cloud Function, as can be seen in this NodeJS example:

/**
 * Google Cloud Function entry-point
 * @param {object} cloudEvent Cloud event data
 */
function helloWorld(cloudEvent) {
   // Decode from Base64
   const dataBuffer = new Buffer(cloudEvent.data);
   const messageData = dataBuffer.toString("base64");

   // Do something with the message
   console.log(`Pub/Sub message data: '${messageData}'`);
}

Debugging event signature functions with Functions Framework

To run and debug Google Cloud Functions with event signature using Functions Framework, the argument signature-type must be set to cloudevent:

functions-framework \
  --source=./dist \
  --signature-type=cloudevent \
  --target=helloWorld

The command above would run locally the Google Cloud Function source code stored in the ./dist directory. It would start an http server listening on http://locahost:8080 and, for each POST request received, it would invoke the helloWorld entry point function passing as first argument the request body content. So, if this curl command is executed...

curl -X POST localhost:8080 \
  -d '{"data":{"message":{"data":"SGVsbG8gd29ybGQh"}}}' \
  -H 'content-type:application/json'

... it would get the JSON object {"data":{"message":{"data":"SGVsbG8gd29ybGQh"}}} as first argument. Once Base64-decoded, the obtained data would be a string with value "Hello world!", representing the Pub/Sub message body.

As explained in the article Debugging Google Cloud Functions in Node, the command above can be completed with different commands to allow debugging (node --inspect) or using environmental variables by using, among others, the NPM package env-cmd.

Comentarios

Entradas populares de este blog

Linting C# in Visual Studio Code

Though very usual in programming environments as Javascript/Typescript, linting , or analyzing code for enforcing a set of coding style rules, is not usually present in the .NET based environments. Rule enforcing is really useful when working on team shared codebases in order to keep them coherent, what in last term reduces both development times and coding errors. A linting example Maybe a practical example would be helpful for explaining what  linting  is to the newcomers (feel free to go on if you aren't). Let's imagine you are a new member in a C# development team that has well established set of coding style rules. Instead (or apart) of putting them in a document, they've adopted a tool that checks these rules during the code building process. Your first code is such ambitious as this: namespace HelloWorld {      using System;      public class Program      {           public static void Main(string[] args)           {                Console

ESlint: Ignore unused underscore variables

Some naming conventions promote the use of the underscore character (" _ ") for those variables that must be declared but are not being used. One common case is that in which a function signature contains some variables that will not be used, as for instance the Express error handlers: app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); In the above example only the arguments err and res are being used, though all four must be defined in the handler signature. Thus, following the naming convention of using underscores for those unused variables, we could recode it as: app.use(function(err, _, res, __) { console.error(err.stack); res.status(500).send('Something broke!'); }); Though it makes the function more readable, it comes with a problem if using ESlint: it will blame by declaring unused variables. error '_' is defined but never used error '__' is define

Using Bitbucket app passwords with git on MacOS (OSX)

Learn how Bitbucket passwords are stored by git on MacOS.