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
See Promise and Promise.all().
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 linesModules
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.
-
Extract the username and check the KV store. Create the user if missing.
show all 18 linesexport 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'); -
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.
-
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
}; -
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
}; -
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.
-
Open PubNub Debug Console.
-
Enter
hello_world
,hello-logger
for the channel and click Subscribe. -
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
.
-
Create a new Before Publish or Fire Function:
show all 31 linesexport 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(); -
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.
-
Open PubNub Debug Console.
-
Enter
hello-world
,hello-universe
for the channel and click Subscribe. -
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
Method | Arguments | Description |
---|---|---|
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
Attribute | Type | Definition |
---|---|---|
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
Attribute | Type | Definition |
---|---|---|
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
Method | Arguments | Description |
---|---|---|
send | body:String (Optional) | Returns a promise that resolves to the value of the response object. |
response
attributes
Attribute | Type | Definition |
---|---|---|
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
Method | Arguments | Description |
---|---|---|
ok | N/A | Returns a promise that resolves to the value of the response object. |
event
attributes
Attribute | Type | Definition |
---|---|---|
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
Method | Arguments | Description |
---|---|---|
ok | N/A | Returns a promise that resolves to the value of the response object. |
event
attributes
Attribute | Type | Definition |
---|---|---|
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.
-
Log in to the Admin Portal and go to Functions v2.
-
Create a Package.
Click Create package. Choose Configure your own. Enter a Package name and description. Click Next.
-
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. -
Open the new Package to see the initial Revision. To edit code, click Edit code or Edit Latest on the Package Revision list.
-
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
} -
Click Save. Changing the Function code creates a new Revision. Enter a Revision name and description and save.
-
To deploy the Package Revision with the Function, click Deploy.
-
Select Add keyset to choose the keysets to run the Function on. Click Create.
-
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:
- Open the Function editor by clicking Edit code or Edit Latest on the Package Revision list.
- Switch to the Debug tab.
- 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.