Skip to main content

3. Make it your own

In the next 5 minutes we will take you through making your first changes to a Wasm application written in Rust. If you haven't got the demo running yet, check out the quick start guide.

3. Making it Your Own

Prerequisites

As a reminder, since we'll be editing Rust code, make sure you have Rust installed, and ensure you have a WebAssembly target added to your toolchain. You can add this target with:

rustup target add wasm32-unknown-unknown

Generating a New Actor

Let's see how easy it is to update an application with new code. First we'll generate a new actor project.

cosmo new actor --git https://github.com/cosmonic/awesome-cosmonic --subfolder xkcdgenerator my-xkcd

This command generated a git repository in the my-xkcd directory with everything you need to compile and run your actor. Other than the code itself, the most important file here is wasmcloud.toml. This file contains metadata for your project, including the claims, which are a set of capabilities that your actor may use (think of the capability providers mentioned earlier.)

claims = ["wasmcloud:httpserver", "wasmcloud:httpclient", "wasmcloud:builtin:numbergen"]

We have three claims in this actor already: the HTTP server to respond to requests, the HTTP client to get images, and numbergen to generate random numbers.

Compiling and Signing an Actor

Building an actor takes just one command:

cosmo build

This command uses your local toolchain to compile the actor into a WebAssembly module. It then signs your actor. Signing the actor is mandatory before it can run on a host and it ensures each unit of code is unique, identifiable and can only use specified capabilities. This is a key part of the wasmCloud security model.

Launching an Actor Locally

Once again, launching an actor is a single command:

cosmo launch

All actors run in a host. cosmo launch runs your actors in a local host (and starts a host for you, if one is not already running). Unpacking this, the first time you run cosmo launch we will start wasmCloud on your machine (a new host), then start an actor on that new host!

If you return to the Logic View, you'll see a new actor has appeared in your constellation. It has a similar name to the one that you started with. However, you'll notice the new actor has a different icon. The Cosmonic UI provides a visual indicator of whether your components are running on a host managed by Cosmonic.

However, it doesn't matter whether your components are running on a Cosmonic host or a host on your laptop locally. Cosmonic is designed for distributed applications; whether parts of your application are running on a laptop, in a cloud provider's VM, or on a Raspberry Pi is irrelevant!

Using your actor in an application

Let's replace our prebuilt tutorial actor with your custom actor. You should have a Registry URL from the output of the above cosmo launch command, you can always run the command again to retrieve this.

Head to the XKCD Application View in Cosmonic. Click Create New Version and then replace the xkcd image property with your own registry URL. Modify the metadata annotation version in order to save this as a new application manifest, then click Save & Deploy.

Updated Application Manifest

Version format

Versions are opaque strings, so you can use whatever you like. We recommend using a semantic versioning scheme, though for this tutorial it's nice to see the difference in how you're distributing the application on the version page.

A New Application URL

Your own actor is linked up and ready to go! It's using all the same capabilities as the prebuilt tutorial actor, and we created a brand new URL to route incoming HTTP requests to your actor. Take a look at the Logic View and you should see a new wormhole node alongside the one created for the prebuilt actor.

Now we can click on the new wormhole node that has appeared on the canvas. This will open a side panel with details about your new wormhole. From here, we click the "Access your Wormhole" button to open a new tab. You should see another XKCD comic! This time, the comics are being generated by your own actor.

The Flexibility of Distributed Applications

Notice what you didn't do: start any new capability providers. Your new actor is running locally, but it's connected to the capability providers running on Cosmonic. This isn't unique to actors, either; you can also run capability providers locally, and connect them to actors running anywhere!

Updating an Actor

Let's return to the new actor. The source code is in src/lib.rs. Open this file and we can take a look at what this does.

The actor implements a single function handle_request. In this function, we generate a random number, issue an HTTP request to the XKCD API, and return an HTML response (which is rendered by your browser).

The random number is generated in a range, representing the list of comic IDs which were valid at the time this template was first written. This is being done using one of the capability providers which are built into the host that your actor is running on (another is a logging capability). These work the same way (through contracts and claims), but you don't need to explicitly start a provider to access these capabilities.

At the time of writing, 2779 was the latest comic ID. Since some time has passed, you could increase the upper end of the range to the new maximum comic ID. Or, you could restrict the range, or eliminate the randomness altogether and always request the same comic! A personal favorite is #1053.

In your editor, change the logic related to selecting a comic down in the handle_inner function. For example:

let comic_num = random_in_range(1053, 1053).await?; // Sample from the best 😉

Once you've updated your actor's code, you can launch a new version by running:

cosmo launch

cosmo will take care of replacing your actor with the updated code. If you refresh the tab connected to your wormhole, you'll see the results of your changes! It's that easy to iterate quickly on your ideas.

What else made this work?

This XKCD application used three capabilities: HTTP Server, HTTP Client, and (builtin) numbergen. This allowed our app to receive/reply to HTTP requests through a wormhole and query an external API. Notice the lack of boilerplate details in this code: no ports, no TLS certificates, and yet you were able to make a request and receive your response. Cosmonic believes this is the way applications should be built. In other words, Write the Right Code. Let us handle the rest.

To make more dynamic applications, you'll want to explore more capabilities.

What next?

Now that you have been through a fun example, we recommend looking at serving files over HTTP. Check out our next example app to get started: https://cosmonic.com/docs/to-build/blobby