Get to know Sat, the WebAssembly function server

Get to know Sat, the WebAssembly function server

So you want to run a piece of code on a server. You want to deploy it without any hassle, and you want it to 'just work', even if you get some heavy traffic. You want to use a familiar language, and you want to ensure you're keeping things secure. Perhaps you want to add a simple function to an existing application, or maybe you want to stand up a simple endpoint to augment a static web application to do the JAMStack thing. These are the best use-cases for Sat, the tiny (but mighty) WebAssembly function server.

logo-sat-wide

Sat is designed to run a function, compiled to WebAssembly (from languages like JavaScript/TypeScript, Go, Rust, and more) as efficiently as possible, and with minimum complexity. In almost every case, you'll be able to deploy a function with absolutely zero config. Since Sat is a statically compiled binary, and it is built to run in any environment, it works equally well in a gigantic Kubernetes cluster as well as on a tiny edge device.

Previous blog posts I’ve written have shown a few different examples for how to run functions on Sat, and those are just the tip of the iceberg. The thing we use Sat for the most is getting code running without the hassle of boilerplate. Take an example CSV to JSON converter, written in TypeScript.

It takes only 3 commands to go from 0 to fully production-ready service, starting with creating the function:

subo create runnable csv-to-json --lang typescript

And then adding your handler code:

import { log } from "@suborbital/runnable";
import * as Papa from "papaparse";

export const run = (input: string): string => {
  let rows = Papa.parse(input, {header: true}).data;

  log.info("parsed " + rows.length + " rows of CSV into JSON");

  return JSON.stringify(rows);
};

And then build and run:

subo build
SAT_DOMAIN=csv-json.example.com sat ./csv-to-json.wasm

And that is it. No configuration files or boilerplate. Just point your DNS record to the service, and Sat will acquire a TLS certificate to start serving traffic. Sat autoscales internally to ensure large amounts of traffic can be handled. Since Sat is based on the rock-solid Wasmtime WebAssembly runtime, it supports all of the WASI standardized APIs, as well as our extended capabilities for calling HTTP services, connecting to databases and caches, and accessing files.

The sandboxing properties of Wasm ensure that potentially malicious third-party code cannot steal your data or attack your infrastructure. In the case above, you can imagine wanting to protect any sensitive user data stored in those CSV files. In order to prevent a wayward NPM library from exfiltrating data to a remote attacker, or to keep your team safe from attacks like Log4j, the protection of WebAssembly is essential to help let us rest easy.

For testing, Sat has a very handy stdin mode that allows executing your function from the command-line. This can be useful for running integration tests or even building small CLI tools. Locally on your machine, you can verify that your code works as expected before deploying it:

cat test.csv | sat --stdin ./csv-to-json.wasm

And finally, Sat can be embedded into your Go application. We've recently made Sat available as a library, so loading and executing WebAssembly functions is as simple as running go get github.com/suborbital/sat:

contents, _ := ioutil.ReadFile("./test.csv")

config, _ := sat.ConfigFromRunnableArg("./csv-to-json.wasm")

s, _ := sat.New(config, nil)

resp, err := s.Exec(contents)
if err != nil {
    log.Fatal(err)
}

fmt.Println("%s", resp.Output)

All in all, Sat is by far the fastest way to get up and running with a secure and ridiculously scalable web service written in a language you already know. WebAssembly's incredible performance characteristics keep your application running smoothly, even under load, and it can run on anything from huge server farms to Raspberry Pis. Give Sat a try, and let us know how it goes by joining our Discord!