Relational Database Storage
Spin provides two interfaces for relational (SQL) databases:
- A built-in SQLite Database, which is always available and requires no management on your part.
- “Bring your own database” support for MySQL and PostgreSQL, where you host and manage the database outside of Spin.
This page covers the “bring your own database” scenario. See SQLite Storage for the built-in service.
Why do I need a Spin interface? Why can't I just use my language's database libraries?
The current version of the WebAssembly System Interface (WASI) doesn’t provide a sockets interface, so database libraries that depend on sockets can’t be built to Wasm. The Spin interface means Wasm modules can bypass this limitation by asking Spin to make the database connection on their behalf.
Using MySQL and PostgreSQL From Applications
The Spin SDK surfaces the Spin MySQL and PostgreSQL interfaces to your language. The set of operations is the same across both databases:
The exact detail of calling these operations from your application depends on your language:
Want to go straight to the reference documentation? Find it here.
MySQL functions are available in the spin_sdk::mysql
module, and PostgreSQL functions in the spin_sdk::pg
module. The function names match the operations above. This example shows MySQL:
use spin_sdk::mysql::{self, Connection, Decode, ParameterValue};
let connection = Connection::open(&address)?;
let params = vec![ParameterValue::Int32(id)];
let rowset = connection.query("SELECT id, name FROM pets WHERE id = ?", ¶ms)?;
match rowset.rows.first() {
None => /* no rows matched query */,
Some(row) => {
let name = String::decode(&row[1])?;
}
}
Notes
- Parameters are instances of the
ParameterValue
enum; you must wrap raw values in this type. - A row is a vector of the
DbValue
enum. Use theDecode
trait to access conversions to common types. - Using PostgreSQL works in the same way, except that you
use
thespin_sdk::pg
module instead ofspin_sdk::mysql
. - Modified row counts are returned as
u64
. (MySQLexecute
does not return the modified row count.) - All functions wrap the return in
anyhow::Result
.
You can find complete examples for using relational databases in the Spin repository on GitHub (MySQL, PostgreSQL).
For full information about the MySQL and PostgreSQL APIs, see the Spin SDK reference documentation.
Granting Network Permissions to Components
By default, Spin components are not allowed to make outgoing network requests, including MySQL or PostgreSQL. This follows the general Wasm rule that modules must be explicitly granted capabilities, which is important to sandboxing. To grant a component permission to make network requests to a particular host, use the allowed_outbound_hosts
field in the component manifest, specifying the host and allowed port:
[component.uses-db]
allowed_outbound_hosts = ["postgres://postgres.example.com:5432"]
Configuration-Based Permissions
You can use application variables in the allowed_outbound_hosts
field. However, this feature is not yet available on Fermyon Cloud.