CNCF and Synadia Align on Securing the Future of the NATS.io Project. Read the joint press release.
NATS Docs
NATS.ioNATS by ExampleGitHubSlackTwitter
  • Welcome
  • Release Notes
    • What's New!
      • NATS 2.11
      • NATS 2.10
      • NATS 2.2
      • NATS 2.0
  • NATS Concepts
    • Overview
      • Compare NATS
    • What is NATS
      • Walkthrough Setup
    • Subject-Based Messaging
    • Core NATS
      • Publish-Subscribe
        • Pub/Sub Walkthrough
      • Request-Reply
        • Request-Reply Walkthrough
      • Queue Groups
        • Queueing Walkthrough
    • JetStream
      • Streams
      • Source and Mirror Streams
        • Example
      • Consumers
        • Example
      • JetStream Walkthrough
      • Key/Value Store
        • Key/Value Store Walkthrough
      • Object Store
        • Object Store Walkthrough
      • Headers
    • Subject Mapping and Partitioning
    • NATS Service Infrastructure
      • NATS Adaptive Deployment Architectures
    • Security
    • Connectivity
  • Using NATS
    • NATS Tools
      • nats
        • nats bench
      • nk
      • nsc
        • Basics
        • Streams
        • Services
        • Signing Keys
        • Revocation
        • Managed Operators
      • nats-top
        • Tutorial
    • Developing With NATS
      • Anatomy of a NATS application
      • Connecting
        • Connecting to the Default Server
        • Connecting to a Specific Server
        • Connecting to a Cluster
        • Connection Name
        • Authenticating with a User and Password
        • Authenticating with a Token
        • Authenticating with an NKey
        • Authenticating with a Credentials File
        • Encrypting Connections with TLS
        • Setting a Connect Timeout
        • Ping/Pong Protocol
        • Turning Off Echo'd Messages
        • Miscellaneous functionalities
        • Automatic Reconnections
          • Disabling Reconnect
          • Set the Number of Reconnect Attempts
          • Avoiding the Thundering Herd
          • Pausing Between Reconnect Attempts
          • Listening for Reconnect Events
          • Buffering Messages During Reconnect Attempts
        • Monitoring the Connection
          • Listen for Connection Events
          • Slow Consumers
      • Receiving Messages
        • Synchronous Subscriptions
        • Asynchronous Subscriptions
        • Unsubscribing
        • Unsubscribing After N Messages
        • Replying to a Message
        • Wildcard Subscriptions
        • Queue Subscriptions
        • Draining Messages Before Disconnect
        • Receiving Structured Data
      • Sending Messages
        • Including a Reply Subject
        • Request-Reply Semantics
        • Caches, Flush and Ping
        • Sending Structured Data
      • Building Services
      • JetStream
        • JetStream Model Deep Dive
        • Managing Streams and consumers
        • Consumer Details
        • Publishing to Streams
        • Using the Key/Value Store
        • Using the Object Store
      • Tutorials
        • Advanced Connect and Custom Dialer in Go
    • Running Workloads on NATS
      • Getting Started
        • Installing Nex
        • Building a Service
        • Starting a Node
        • Deploying Services
        • Building a Function
        • Deploying Functions
      • Host Services
        • Javascript | V8
      • Nex Internals
        • Architecture Overview
        • Node Process
        • Nex Agent
        • No Sandbox Mode
        • Root File System
        • Control Interface
      • FAQ
  • Running a NATS service
    • Installing, running and deploying a NATS Server
      • Installing a NATS Server
      • Running and deploying a NATS Server
      • Windows Service
      • Flags
    • Environmental considerations
    • NATS and Docker
      • Tutorial
      • Docker Swarm
      • Python and NGS Running in Docker
      • JetStream
      • NGS Leaf Nodes
    • NATS and Kubernetes
    • NATS Server Clients
    • Configuring NATS Server
      • Configuring JetStream
        • Configuration Management
          • NATS Admin CLI
          • Terraform
          • GitHub Actions
          • Kubernetes Controller
      • Clustering
        • Clustering Configuration
        • v2 Routes
        • JetStream Clustering
          • Administration
          • Troubleshooting
      • Super-cluster with Gateways
        • Configuration
      • Leaf Nodes
        • Configuration
        • JetStream on Leaf Nodes
      • Securing NATS
        • Enabling TLS
        • Authentication
          • Tokens
          • Username/Password
          • TLS Authentication
            • TLS Authentication in clusters
          • NKeys
          • Authentication Timeout
          • Decentralized JWT Authentication/Authorization
            • Account lookup using Resolver
            • Memory Resolver Tutorial
            • Mixed Authentication/Authorization Setup
        • Authorization
        • Multi Tenancy using Accounts
        • OCSP Stapling
        • Auth Callout
      • Logging
      • Enabling Monitoring
      • MQTT
        • Configuration
      • Configuring Subject Mapping
      • System Events
        • System Events & Decentralized JWT Tutorial
      • WebSocket
        • Configuration
    • Managing and Monitoring your NATS Server Infrastructure
      • Monitoring
        • Monitoring JetStream
      • Managing JetStream
        • Account Information
        • Naming Streams, Consumers, and Accounts
        • Streams
        • Consumers
        • Data Replication
        • Disaster Recovery
        • Encryption at Rest
      • Managing JWT Security
        • In Depth JWT Guide
      • Upgrading a Cluster
      • Slow Consumers
      • Signals
      • Lame Duck Mode
      • Profiling
  • Reference
    • FAQ
    • NATS Protocols
      • Protocol Demo
      • Client Protocol
        • Developing a Client
      • NATS Cluster Protocol
      • JetStream wire API Reference
    • Roadmap
    • Contributing
  • Legacy
    • nats-account-server
Powered by GitBook
On this page
  • Writing a JavaScript Function
  • Writing a WebAssembly Function
  • Host Services

Was this helpful?

Edit on GitHub
Export as PDF
  1. Using NATS
  2. Running Workloads on NATS
  3. Getting Started

Building a Function

PreviousDeploying ServicesNextDeploying Functions

Last updated 11 months ago

Was this helpful?

Nex functions can be thought of as similar to cloud functions or "lambdas". Nex functions are short-lived and are executed in response to some external trigger.

There are two kinds of Nex functions: JavaScript and WebAssembly. We'll take a look at both of those in this section of the guide.

Nex functions are undergoing rapid change as we bring the entire project closer toward a 1.0. Both JavaScript functions and WebAssembly functions will experience a number of API changes as we provide host services (see below) to both and leverage the component model for Wasm workloads. Make sure you check the examples folder frequently to see if anything has changed.

Writing a JavaScript Function

Writing a JavaScript function is as easy as it sounds. Write the function that does what you need it to do and you're ready to go. For example, here's a JavaScript function that works in Nex and simply "echoes" the incoming request:

(subject, payload) => {
  console.log(subject);
  return payload;
};

Here the function is passed two parameters:

  • subject - The subject on which the function was triggered (we'll cover trigger subjects in the next section on deployment)

  • payload - The raw binary payload that was supplied along with the trigger

The function returns a binary payload to be used as the response (or an empty payload for no response). Note that as it stands, the function can produce very few side effects. As we grow the "host services" (discussed shortly) functionality, JavaScript functions will be able to leverage more of NATS's core functionality and JetStream.

While you'll only be deploying the single .js file, you're free to use whatever other testing and build tools you like.

Writing a WebAssembly Function

In order to support the largest possible number of languages and runtimes, Nex's functions follow the using . This means that the module's main (or start or _start depending on your perspective) function is executed every time a trigger occurs and input is supplied via stdin and the function's response is provided via stdout.

Nex-compatible WebAssembly functions can be written in any language that can generate a freestanding wasm32-wasi module that has no host JavaScript requirements. For example, if you're writing a wasm function in Go and you've imported syscall/js directly or transitively, your function isn't going to work.

In this section we're going to create a WebAssembly function for Nex using Rust, one of the most well-tooled languages in the WebAssembly ecosystem. Don't worry if you don't have Rust installed, you can still follow along and deploy a pre-built module in the next section.

Create a new Rust executable project (not library). Modify the Cargo.toml file to read as follows:

[package]
name = "echofunction"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "echofunction"
path = "src/main.rs"

Now edit src/main.rs to have the following contents:

use std::{env, io::{self, Read, Write}};

fn main() {
    let args: Vec<String> = env::args().collect();

    // When a WASI trigger executes:
    // argv[1] is the subject on which it was triggered
    // stdin bytes is the raw input payload
    // stdout bytes is the raw output payload

    let mut buf = Vec::new();
    io::stdin().read_to_end(&mut buf).unwrap();
    
    let mut subject = args[1].as_bytes().to_vec();
    buf.append(&mut subject);

    // This just returns the payload concatenated with the
    // subject
    
    io::stdout().write_all(&mut buf).unwrap();
}

This Rust WebAssembly function takes the subject on which it was triggered and an incoming payload and returns that payload prepended by the subject. This way it's easy to see what's happening when you trigger the function.

Build this function into a module using the following command:

$ cargo build --target wasm32-wasi --release

This will put echofunction.wasm in the ./target/wasm32-wasi/release directory. This function takes up about 2MB but can be shrunk down below 700KB using public wasm tools. Your deployable WebAssembly functions use less disk space than even the smallest of memes.

Host Services

Lambda functions deployed in AWS have access to a subset of the AWS SDK, likewise with functions deployed in Azure and Google. Even so-called "edge functions" have access to tiny, optimized, edge versions of resources like key-value buckets, object stores, and more.

During the first experimental pre-release phase, we have a small number of services available for functions. At the moment, JavaScript functions have access to the following host services:

  • Core Messaging, e.g. Pub, Sub, Request

  • Key-Value Store

  • Object Store

  • HTTP Client

If the WASI component model for WebAssembly matures enough to the point where we think it will give our developers a worthy experience, then we can provide host services through the "WASI cloud" set of contracts. If the component model doesn't support a good enough developer experience within our timeframe, then we may end up providing our own contracts for host services.

Stay tuned to our blog and social media outlets for news as we enhance and provide more host services.

Small, fast functions like this are perfect for doing things like transforming data or performing ad hoc calculations. As such, they lend themselves to being used as "". A pure function is just a function that has no side effects.

However, not everything people need to do with functions can be represented as a pure function with no I/O or side effects. This is where come in. In nearly every FaaS or Cloud Function runtime available in the cloud, you usually get access to some kind of SDK that grants your function some basic capabilities.

WebAssembly
command pattern
WASI
pure functions
host services