Announcing Spin v0.8.0
Radu Matei
spin
wasm
wasi
Spin is an open source developer tool for building and running serverless functions and microservices with WebAssembly. Right before the end of 2022, we announced Spin v0.7, which brought a few new features — most notably, an integration with HashiCorp Vault for runtime secrets and configuration, new JavaScript and TypeScript SDKs, and initial MySQL support from Spin SDKs.
Today, we are pleased to announce a new release of Spin, v0.8.0. This release adds a few new improvements to the JavaScript and TypeScript SDKs and a host of bugfixes and small improvements. But most importantly, this release lays the groundwork for a few foundational areas of work in Spin: building external triggers to extend the core functionality of Spin through plugins, tackling the software supply chain of the project, and distributing Spin applications using existing container registry services.
Let’s explore some of the new features that we worked on in January.
Routing in JavaScript and TypeScript
With the latest update to the JavaScript and TypeScript SDKs for Spin, we are introducing a new router based on itty-router
, a popular open source router for JavaScript. This will simplify how a component that needs to do internal routing beyond the spin.toml
routes is written, removing the boilerplate.
You can now instantiate a router, then write, for example, router.get("/path", (req) => console.log(req))
.
Here is a complete example:
import { HandleRequest, HttpRequest, HttpResponse } from "@fermyon/spin-sdk"
const encoder = new TextEncoder()
const router = utils.Router();
// Handle the /hello route.
router.get("/hello", (req) => {
return {
status: 200,
body: encoder.encode("Hello, Spin! Handling route " + req.url).buffer
}
});
// Handle the /projects/:id route, and extract the route parameters as arguments to the router handler.
router.get("/products/:id", ({ params }): HttpResponse => {
return {
status: 200,
body: encoder.encode("Handling product ID: " + params.id).buffer,
}
});
// handleRequest is the entrypoint to the Spin handler.
export const handleRequest: HandleRequest = async function(request: HttpRequest): Promise<HttpResponse> {
return await router.handleRequest(request);
}
We would like to gather feedback on using a language-specific router to build HTTP components with Spin SDKs. If you are interested in seeing HTTP routers in other SDKs, please let us know in our Discord community.
TLS connections for Redis, MySQL, and PostgreSQL
Spin has built-in support for connecting to Redis, MySQL, and PostgreSQL databases through the various language SDKs. In Spin v0.8, we updated our implementations to ensure users can access those databases over TLS connections.
Below is an example of using the Rust SDK for Spin to connect to a Redis database running in Upstash over a TLS connection:
/// Spin HTTP component that connects to a Redis database.
#[http_component]
fn connecting_to_redis(_req: Request) -> Result<Response> {
let value = spin_sdk::redis::incr(
"rediss://<user>:<password>@<database-name>.upstash.io:37678",
"counter",
)
.map_err(|_| anyhow!("Error querying Redis"))?;
let res = format!("Hello from Upstash! Counter value is {}", value);
Ok(http::Response::builder()
.status(200)
.body(Some(res.into()))?)
}
Distributing Spin applications using OCI registries
Since the launch of Spin, we have been distributing applications using Bindle, an aggregate object storage project originally designed to distribute WebAssembly applications.
As we have observed more and more users building applications with Spin, one of the common asks has been to distribute applications using existing container registries such as the GitHub Container Registry or DockerHub.
In v0.8.0, we are releasing a preview for distributing Spin applications using container registries using the spin oci
commands. First, let’s see how to push a simple Spin application to the GitHub Container Registry:
$ spin oci push ghcr.io/radu-matei/spin-hello-world:v1
Pushed "https://ghcr.io/v2/radu-matei/spin-hello-world/manifests/sha256:06b19f4394c59fe943140c9b59f083aefd4b53c6b632758523a2800d819a1575"
We can now see the artifact in the GitHub UI:
For now, the spin oci push
command assumes you have logged in to the target registry using other tooling (such as docker login
or registry specific tooling). In the next version of Spin, we will introduce spin oci login
to help with logging in registries without depending on external tools.
To mark this functionality as still early and experimental, instead of integrating it directly into spin up
, this release adds a temporary spin oci run
command for running an application given a registry reference:
# after building your application with `spin build`:
$ spin oci run ghcr.io/radu-matei/spin-hello-world:v1
In the next version of Spin, running an application from an OCI registry will be integrated into spin up
.
Behind the scenes, Spin uses the OCI Artifacts project to use existing container registries to distribute Spin applications. If you are interested in diving into the details of how this is implemented, have a look at the proposal and at the implementation. If you are interested in shaping how registry support will look in the next version, please share your thoughts in our Discord community.
Signing and verifying Spin applications using Cosign and Sigstore
Because of the experimental OCI support, we can further take advantage of ecosystem tools such as Cosign to securely sign and verify your Spin applications:
$ COSIGN_EXPERIMENTAL=1 cosign sign ghcr.io/radu-matei/spin-hello-world@sha256:06b19f4394c59fe943140c9b59f083aefd4b53c6b632758523a2800d819a1575
Generating ephemeral keys...
Retrieving signed certificate...
tlog entry created with index: 12519542
Pushing signature to: ghcr.io/radu-matei/spin-hello-world
$ COSIGN_EXPERIMENTAL=1 cosign verify ghcr.io/radu-matei/spin-hello-world@sha256:06b19f4394c59fe943140c9b59f083aefd4b53c6b632758523a2800d819a1575
Verification for ghcr.io/radu-matei/spin-hello-world@sha256:06b19f4394c59fe943140c9b59f083aefd4b53c6b632758523a2800d819a1575 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- Any certificates were verified against the Fulcio roots.
As the OCI support for Spin matures, and as we gather feedback, we will continue to improve the support for signing and verifying Spin applications using ecosystem tools.
Extending Spin with external triggers and plugins
Over the last few releases, we have been quietly improving the support for building Spin plugins that add functionality and new subcommands without modifying the Spin codebase.
One such plugin is making JavaScript and TypeScript support for Spin possible. When running spin build
on an application that uses one of the JavaScript templates, behind the scenes Spin will execute spin js2wasm
to package the application into a Wasm module. js2wasm
is not built into Spin, but rather it is an entirely separate project, with a separate codebase and release cycle.
Anyone can build a plugin and extend Spin with custom functionality. js2wasm
is specific for JavaScript, and there might be a plugin for Python in the future.
But language-specific plugins are just one of the use cases. You can also extend the functionality of spin up
by building a special type of plugins called “trigger plugins”, which were added as experimental in this latest release. If you are interested in building custom triggers for Spin (such as cron jobs or queue triggers), here is an early example of how this will look like..
Looking forward
We are excited about the work we have already started for version v0.9.0! The biggest upcoming feature is having a built-in key/value storage and API that we can directly use from a Spin application. The API will be based on the wasi-keyvalue
specification, and you can follow along with the proposal and with the implementation.
Thank you
We would like to thank the over 50 contributors and everyone who has been filing bug reports and suggestions. Thank you for making Spin better every day!
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!