Functions Development Guidelines

Functions modules and API

For more information about Functions modules or the public REST API (for Functions v2), see the Functions Modules and REST API docs.

Introduction

This page shows how to run Functions after you create and configure them. For an overview, see Functions Basics.

  • PubNub provides integrations through the Integration Catalog.
  • Functions are JavaScript modules with a default export Function. See guidelines for each event type.
  • PubNub provides modules to help you develop Functions.
  • Asynchronous operations use Promises. See Promises.
  • You can chain up to 3 Functions to run in sequence. See Chaining Functions.

Development guidelines

Code structure

For all event types except On Request, use this structure:

export default (request) => {
// Your business logic here
return request.ok();
// request.abort(); to fail execution
};

For all event types except On Request and On Interval, the request object has two methods: ok() and abort(). The response object isn’t available. For details, see On Request and On Interval.

On Request

Use this structure:

export default (request, response) => {
// Your code here
return response.send();
};

For On Request, the request object has json(), and the response object has send(). For details, see On Request.

On Interval

Use this structure:

export default (event) => {
// Your code here
return event.ok();
};

For On Interval, the event object has ok(). For details, see On Interval Inputs/Outputs.

Promises

Asynchronous operations use Promises (ES6). promise is implicitly available for every Function.

const Promise = require('promise'); // No need to add this line
Learn more

Promise.all()

You can use Promise.all() to run multiple async calls in parallel.

Example: fetch a username from KV Store and an IP address from a web service. When both resolve, update the request.

export default (request) => {
const store = require('kvstore');
const xhr = require("xhr");

const fullName = store.get('fullName');
const ipAddress = xhr.fetch("https://httpbin.org/ip");

return Promise.all([fullName, ipAddress])
.then((values) => {

request.message.fullNameResult = values[0];
request.message.ip = JSON.parse(values[1].body).origin;

return request.ok();
})
show all 20 lines

Modules

Use modules to optimize performance and add specialized functionality. This keeps each Function focused on its event.

For the full list, see Functions modules.

Webhooks on request

You can use an On Request event type to create webhooks.

Example: check whether a username exists. Assume username is passed as a query parameter.

  1. Extract the username and check the KV store. Create the user if missing.

    export default (request, response) => {

    const db = require('kvstore');
    const username = request.params.username;

    return db.get(username).then((dataFromDb) => {
    if (!dataFromDb) {
    console.log('The username does not exist.');
    db.set(username, {});
    response.status = 200;
    return response.send('Username is available');
    } else {
    console.log('The username already exists.');
    response.status = 409;
    return response.send('Username already exists');
    show all 18 lines
  2. Save changes and, depending on your Functions version (v1 or v2), either restart the module or create a new Package Revision and deploy it.

Now test the Function.

Chaining

Functions can run in sequence or based on a condition. Use pubnub.publish(), pubnub.signal(), or pubnub.triggerRequestFunction().

Modules/Packages for chained Functions

Place Functions you plan to chain in the same Module/Package. It’s easier to start/stop them.

Chain Functions

Example: capture messages on hello-world and send them to the hello-logger Function.

  1. Create an On Before Publish or Fire hello-logger Function:

    export default (request) => {
    console.log(request) // show what we have inside
    return request.ok() // done
    };
  2. Create an On Before Publish or Fire hello-world Function:

    export default (request) => {
    const pubnub = require('pubnub');

    pubnub.publish({
    "channel": "hello-logger",
    "message":request.message
    }).then((publishResponse) => {
    console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`);
    }).catch((err) => {
    console.error(err);
    });

    return request.ok(); // Return a promise when you're done
    };
  3. Save the changes and, depending on your Functions version (v1 or v2), either restart the Module or create a new Package Revision and deploy it.

  4. Open PubNub Debug Console.

  5. Enter hello_world, hello-logger for the channel and click Subscribe.

  6. Back on the Functions screen, publish the test payload.

Fork Functions

Example: capture messages on hello-world, add "Hello": "World", and publish to hello-universe as well as hello-world.

  1. Create a new Before Publish or Fire Function:

    export default (request) => {
    const db = require('kvstore');
       const pubnub = require('pubnub');

       console.log('The message ', request.message, ' was published on ', request.channels[0], ' via ', request.meta.clientip);

       request.message.hello = 'world!'; // augment hello = world

    // To fork return pubnub.publish and include request.ok in the .then()
    return pubnub.publish({
        "channel": "hello_universe",
           "message": request.message
       }).then((publishResponse) => {
    console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`);
        return request.ok();
    show all 31 lines
  2. Save the changes and, depending on your Functions version (v1 or v2), either restart the Module or create a new Package Revision and deploy it.

  3. Open PubNub Debug Console.

  4. Enter hello-world, hello-universe for the channel and click Subscribe.

  5. Back on the Functions screen, publish the test payload.

Avoid infinite loops

You can chain or fork publishes across many channels. Avoid scenarios that can loop (for example, A -> B -> A). The system detects and blocks infinite loops, but ensure your logic doesn’t rely on this.

Recursion limit

The maximum recursion limit is 3 hops from one Function to another. Using publish or fire, you can execute at most three Functions.

Within a single Function execution, the combined maximum number of KV store operations, XHRs, publish, and fire is 3.

Request/Response objects

All event types except On Request

request methods

MethodArgumentsDescription
ok
message:String (Optional)
Returns a promise that resolves to the value of the request object.
abort
message:String (Optional)
Returns a promise that resolves to the value of the request object, with an error code.

request attributes

AttributeTypeDefinition
message
Object
The actual user message sent to the channel.
verb
String
Method used by the publishing client when sending the message to PubNub.
pubkey
String
The Publish Key used when sending the message.
subkey
String
The Subscribe Key to retrieve the message.
channels
Array<String>
The list of channels on which the message was sent.
version
String
API Version.
meta.clientip
String
IP of the publishing client.
meta.origin
String
Origin defined on the publishing client.
meta.useragent
String
The publishing client's user agent string.
params
Object
URL parameters on the request.
uri
String
The request URI.

On Request Inputs/Outputs

request attributes

AttributeTypeDefinition
verb
String
Method used by the publishing client when sending the message to PubNub. Always set to rest.
pubkey
String
The Publish Key used when sending the message.
subkey
String
The Subscribe Key to retrieve the message.
version
String
API Version.
meta.clientip
String
IP of the publishing client.
meta.origin
String
Origin defined on the publishing client.
meta.useragent
String
The publishing client's user agent string.
params
Object
URL parameters on the request.
uri
String
The full path of the URI minus PubNub hostname information.
path
String
The path minus PubNub and key information. This is the path you configured for the Function.
method
String
HTTP method such as GET, PUT, POST, DELETE.
body
Object
The body content if passed in the request.
headers
Object
Header information passed in the request.

response methods

MethodArgumentsDescription
send
body:String (Optional)
Returns a promise that resolves to the value of the response object.
response attributes
AttributeTypeDefinition
status
Object
HTTP status code returned to the caller.
body
Object
Response body returned to the caller.
headers
Object
Response headers returned to the caller.

On Interval Inputs/Outputs

event methods

MethodArgumentsDescription
ok
N/A
Returns a promise that resolves to the value of the response object.

event attributes

AttributeTypeDefinition
verb
String
Method used by the publishing client when sending the message to PubNub. Always set to interval.
pubkey
String
The Publish Key used when sending the message.
subkey
String
The Subscribe Key to retrieve the message.
execInterval
Number
Duration of the interval in milliseconds.
lastTimestamp
Number
Timestamp of last Function execution.
timestamp
Number
Timestamp of current Function execution.

Subscribe on Interval Inputs/Outputs

event methods

MethodArgumentsDescription
ok
N/A
Returns a promise that resolves to the value of the response object.

event attributes

AttributeTypeDefinition
verb
String
Method used by the publishing client when sending the message to PubNub. Always set to interval.
pubkey
String
The Publish Key used when sending the message.
subkey
String
The Subscribe Key to retrieve the message.
execInterval
Number
Duration of the interval in milliseconds.
lastTimestamp
Number
Timestamp of last Function execution.
timestamp
Number
Timestamp of current Function execution.

Create a Function

This short instruction shows how to create a simple Function in the Admin Portal. The Function changes the message before publishing it on the specified channel.

Admin Portal UI

This section shows how to use the Admin Portal to create PubNub Functions. To learn the Functions UI, see Functions v2.

Set up configuration

You need a Package before you create a Function.

  1. Log in to the Admin Portal and go to Functions v2.

  2. Create a Package.

    Click Create package. Choose Configure your own. Enter a Package name and description. Click Next.

  3. Create a Function.

    Enter a name and select the Before Publish or Fire event type. Set the trigger channel to hello-world. Click Create package.

  4. Open the new Package to see the initial Revision. To edit code, click Edit code or Edit Latest on the Package Revision list.

  5. The editor includes a sample Function. Replace the code to add simple logging and test.

    export default (request) => {

    console.log('request', request);
    request.message.hello = 'world!'; // augment hello = world
    console.log('The message: ', request.message, ' was published on ', request.channels[0], ' via', request.meta.clientip);

    return request.ok(); // Return a promise when you're done
    }
  6. Click Save. Changing the Function code creates a new Revision. Enter a Revision name and description and save.

  7. To deploy the Package Revision with the Function, click Deploy.

  8. Select Add keyset to choose the keysets to run the Function on. Click Create.

  9. If you don’t assign secrets for this example, click Deploy again to create the deployment.

Maximum number of deployments

The number of deployments equals the number of keysets you selected. A Package Revision can run on up to 50 keysets.

Run and test

To test the Function:

  1. Open the Function editor by clicking Edit code or Edit Latest on the Package Revision list.
  2. Switch to the Debug tab.
  3. Click Publish in the Test payload section.

Trigger Functions

A Function triggers on one or more channels (including wildcards), except for On Request, which triggers by HTTP request.

Clients publishing and subscribing on a channel operate independently of Functions. When a parent Package Revision is running, configured Functions process messages seamlessly.

Start a Module/Package

Start a Package Revision by clicking the start button next to a Revision on the list.

When the Package Revision starts, each Function runs across all PubNub data centers for global availability. All Functions run hot (don't go into resource-saving mode) for low latency.

Stop a Module/Package

Stop a Package Revision by clicking the stop button next to a Revision on the list.

When stopped, messages continue to flow through the PubNub Network, and Web API calls to On Request Functions return 404 Not Found until you start the Package Revision again.

Last updated on