Skip to main content
Eric Gregory
Eric Gregory
Eric Gregory
||5 min read

Introducing pluggable PostgreSQL access for your wasmCloud apps

Cross-posted from the wasmCloud blog.

With wasmCloud, you can build applications out of WebAssembly components and pluggable, reusable capabilities, so you can focus on the core logic of your application and abstract away the rest, all using open source standards.

PostgreSQL is one of the most widely used relational database systems. If you want to use a database system like Postgres, wasmCloud makes it easy to simply plug in the functionality in a reusable, language-agnostic way, without wasting time writing boilerplate code.

In this post, we'll show you how to get started with the Postgres capability in wasmCloud.

Speed up development: Write queries without managing connection pools

Enterprise application teams need flexible database options, and for many, PostgreSQL is the tool of choice. But like many basic, non-functional requirements, teams can waste a lot of time getting to grips with libraries in this or that language and worrying about how to implement their database for a given project.

Capabilities abstract away database configuration and remove this toil.

In practice, every wasmCloud capability consists of two parts:

  • An interface: The standard contract for a piece of functionality, defined in WebAssembly Interface Type (WIT), defining an API for any language that uses the interface.
  • A capability provider: The executable that plugs in to wasmCloud and delivers the functionality in question.

In this case, you can use a single API for Postgres operations, regardless of your development language, and simply plug the Postgres capability provider into your application manifest when you deploy to wasmCloud. Because this isn't a one-size-fits-all SQL interface, it can take advantage of Postgres-specific features, like RETURNING * and DDL in queries with explicit BEGIN/COMMIT transactions.

Open standards and portability

Later on, if you need to migrate to another system, that's no problem—the wasmcloud-postgres interface can be used by any system that supports the WIT standard.

Get started with Postgres on wasmCloud

Let's try it out. We'll use a Rust-based component, but you don't really have to be familiar with the language. For this example, you'll just need:

  • The wasmCloud Shell (wash) CLI to build WebAssembly components and deploy to local wasmCloud.
  • cargo (part of the Rust toolchain) to help build from Rust
  • docker to easily run an instance of Postgres.

Start Postgres and wasmCloud locally

First we need to get a Postgres cluster running. We can do this quickly and easily with Docker:

docker run \
    --rm \
    -e POSTGRES_PASSWORD=postgres \
    -p 5432:5432 \
    --name pg \
    postgres:16.2-alpine

In another terminal tab, we'll start our local wasmCloud, using the -d/--detached flag to run in the background:

wash up -d
Reading logs

We're running in detached mode to avoid opening another terminal tab, but if you'd like to check the logs, you can find them at ~/.wash/downloads/wasmcloud.log.

Generate a new project

Now we'll generate a new project using the Rust-based sqldb-postgres-query example from the wasmCloud monorepo as a template.

wash new component postgres-demo \
    --git wasmcloud/wasmcloud \
    --subfolder examples/rust/components/sqldb-postgres-query
cd postgres-demo

If you're familiar with Rust, in src/lib.rs you'll see that the code for querying Postgres is very simple:

impl Guest for QueryRunner {
    fn call() -> String {
        if let Err(e) = query(CREATE_TABLE_QUERY, &[]) {
            return format!("ERROR - failed to create table: {e}");
        };

        match query(
            INSERT_QUERY,
            &[PgValue::Text(format!("inserted example row!"))],
        ) {
            Ok(rows) => format!("SUCCESS: inserted new row:\n{rows:#?}"),
            Err(e) => format!("ERROR: failed to insert row: {e}"),
        }
    }
}

Next build your WebAssembly component from the Rust code.

wash build

The build process generates a folder called build containing sqldb-postgres-query_s.wasm.

Deploy the demo

The next step for a wasmCloud application deployment is usually to define the components and providers you'll be using in a deployment manifest.

For building locally, there is a prebuilt manifest (local.wadm.yaml) in the project directory.

In the interest of security, we'll use the wash config subcommand to define a "named configuration" called default-postgres:

wash config put default-postgres \
    POSTGRES_HOST=localhost \
    POSTGRES_PORT=5432 \
    POSTGRES_USERNAME=postgres \
    POSTGRES_PASSWORD=postgres \
    POSTGRES_DATABASE=postgres \
    POSTGRES_TLS_REQUIRED=false

The Postgres provider knows to use this configuration because of our application manifest (local.wadm.yaml), where we've referred to default-postgres for named configuration.

Now it's time to deploy:

wash app deploy local.wadm.yaml

Confirm the application is deployed:

wash app list

You should see output like the following:

  Name                          Deployed Version              Status
  rust-sqldb-postgres-query     v0.1.0                        Deployed
    └ Demo WebAssembly component using the wasmCloud SQLDB Postgres provider via the wasmcloud:postgres WIT interface

Invoke the demo component

By default, the sqldb-postgres-query component includes a simple invoke interface, which enables using wash call to trigger the component directly via the CLI:

wash call rust_sqldb_postgres_query-querier wasmcloud:examples/invoke.call
SUCCESS: inserted and manually retrieved new row:
[
    [
        ResultRowEntry {
            column-name: "description",
            value: PgValue::Text(
                "inserted example row!",
            ),
        },
    ],
]

Clean up

When you're finished, you can undeploy and delete the application:

wash app delete rust-sqldb-postgres-query

To stop your local wasmCloud:

wash down

Learn more and get involved

Explore the Capability Catalog to learn more about the first and third-party capabilities already available on wasmCloud.

Want to get involved with the community or learn more about building your own components and capabilities? Join us on the wasmCloud Slack!