Announcing Spin v0.7.0
Radu Matei
spin
wasm
wasi
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, ¶ms)?;
// 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!