December 15, 2022

Announcing Spin v0.7.0

Radu Matei Radu Matei

spin wasm wasi

Announcing Spin v0.7.0

We first introduced Spin in March of this year as Fermyon’s vision for building and running fast and secure microservices with Wasm. Since the launch, we have been working on a few main themes for the project:

  • making sure the developer experience for building and running applications with Spin is frictionless
  • building language SDK support for new and exciting languages in Wasm
  • building a place to deploy and run your Spin applications with Fermyon Cloud

Today we are pleased to announce a new release of the Spin project, v0.7.0. This release further focuses on the local developer experience for building WebAssembly microservices. In addition, it adds new integration with HashiCorp’s Vault for managing runtime secrets and support for running Spin on Linux ARM64. There is also experimental support for connecting to MySQL databases.

Since the previous release of Spin, we have also published a new JavaScript and TypeScript SDK and made further improvements around deploying Spin applications on Fermyon Cloud.

Let’s explore some of the new features that made their way into Spin v0.7.0.

The new HashiCorp Vault integration for secrets

HashiCorp Vault is an open source tool that secures, stores, and tightly controls access to tokens, passwords, certificates, or encryption keys, using a UI, CLI, or HTTP API to give secure access to sensitive data.

With the new release, you can use Spin to retrieve sensitive data such as secrets, connection strings, or passwords from HashiCorp Vault.

Let’s see an example. After starting Vault, we can add a sensitive value:

vault server -dev -dev-root-token-id root
vault kv put secret/password value="really-sensitive-value123!"

Now we need to tell Spin to get configuration variables from from this Vault instance. To set this up, we use the new runtime configuration file runtime-config.toml, which spin up reads when it starts:

[[config_provider]]
type = "vault"
url = "<adress-to-vault>"
token = "root"
mount = "secret"

Finally, we can access the secret through the Spin SDK. Below we can see an example of achieving this with the new TypeScript SDK:

export async function handleRequest(request) {
  // this will now get `password` from Vault.
  let password = spinSdk.config.get("password");
  // format a message to return as a response.
  let message = `Retrieved password from Vault: ${password}`;
  return {
    status: 200,
    body: encoder.encode(message).buffer,
  };
}

The Spin SDKs try to simplify such a task as much as possible, and retrieving a configuration variable can be done from JavaScript and TypeScript, Rust, and Go.

Sending a request to our application, we now have access to the data we have securely stored in HashiCorp Vault:

Retrieved password from Vault: really-sensitive-value123!

Refining the developer experience

One of the main goals of the Spin project is to build a frictionless developer experience. Up until this point, the inner loop developer workflow while building an application has been spin new to create an application based on a template, spin build to build that component, then spin up to run the application locally.

This works if the application we are building is made up of a single component, but we’re finding that applications comprised of multiple components are a common pattern as well. To simplify this scenario, we are introducing spin add, which adds a new component to an existing Spin application based on the existing Spin templates:

# update the latest templates and install all templates used:
# spin templates install --git https://github.com/fermyon/spin --update
# spin templates install --git https://github.com/fermyon/spin-js-sdk --update
# create a new empty application
# spin new http-empty && cd app
# now add a JavaScript component
spin add http-js
# and a Go component
spin add http-go

Another thing we learned since launching Spin is that reusing components within an organization or from open source repositories is a common scenario. In this release, we are introducing a way to specify that a component from spin.toml needs to be fetched from a URL, in the example below, from a GitHub release:

[[component]]
id = "ui"
source = {
  url = "https://github.com/fermyon/spin-fileserver/releases/download/v0.0.1/spin_static_fs.wasm",
  digest = "sha256:650376c33a0756b1a52cad7ca670f1126391b79050df0321407da9c741d32375"
}

You can use the new templates for simplifying how to create a component that serves static files or redirects to a given location. In future Spin releases, we plan to further improve the story around sharing existing components, particularly around distributing them using a registry.

New ways to connect to MySQL databases

One of the areas we are constantly trying to improve is around persistence and data services for Spin applications. In this release, we are excited to start the work to support connecting to MySQL databases from Spin applications.

This effort closely tracks the upstream wasi-sql proposal and adds initial support for executing queries and running SQL statements with MySQL databases.

Below is an example of running a SELECT statement using the Rust SDK:

fn get(id: i32) -> Result<Response> {
     // get the MySQL database URL and connection string
     // from the Spin configuration provider, potentially backed by Vault.
     let address = spin_sdk::config::get("database")?;

     // construct the query and execute it
     let sql = "SELECT id, name, prey, is_finicky FROM pets WHERE id = ?";
     let params = vec![ParameterValue::Int32(id)];
     let rowset = mysql::query(&address, sql, &params)?;

     // use the result
     match rowset.rows.first() {
         None => Ok(http::Response::builder().status(404).body(None)?),
         Some(row) => {
             let pet = as_pet(row)?;
             let response = format!("{:?}", pet);
             Ok(http::Response::builder()
                 .status(200)
                 .body(Some(response.into()))?)
         }
     }
 }

We are asking the community for feedback on the database support, and we are considering implementing MySQL support for the other SDKs as well - if you have thoughts about database and persistence in Spin applications, please share your feedback!

New Spin SDKs for JavaScript and TypeScript

Last week we introduced the new Spin SDKs for JavaScript and TypeScript. We are happy to now support JavaScript and TypeScript applications with Spin and Fermyon Cloud. Let’s see an example of the simplest application we can write in JavaScript:

export async function handleRequest(request) {
  return {
    status: 200,
    headers: { "content-type": "text/plain" },
    body: encoder.encode("Hello from JS-SDK").buffer,
  };
}

With the JavaScript and TypeScript SDKs, we are excited to start demonstrating how to use new serverless databases such as PlanetScale, which we will showcase in the coming weeks. In the meantime, you can get a sneak peek at one of our future examples.

Other improvements to Spin

This release is packed with lots of small improvements and bug fixes:

Thank you

Finally, we would like to thank the almost 50 contributors and everyone who has been filing feature requests and bug reports, as well as everyone contributing to the Bytecode Alliance Wasmtime and component model projects!

We are really excited for you to try Spin — head over to the Spin documentation website to give it a spin, and please fill out the Spin survey.

If you are interested in Spin, Fermyon Cloud, or other Fermyon projects, join the chat in the Fermyon Discord server and follow us on Twitter @fermyontech!


🔥 Recommended Posts


Quickstart Your Serveless Apps with Spin

Get Started