Atmo Beta-3: Streams, Connections, and Auth, oh my!

Atmo Beta-3: Streams, Connections, and Auth, oh my!

This week we released Atmo Beta-3, its most capable release yet! The focus for this release was on flexibility and connectivity; in addition to supporting several languages such as TypeScript, Rust, and Swift, we want Atmo to provide all of the building blocks you need to build powerful systems. Working towards the goal of Atmo being the simplest and most secure way to build your API services, backend systems, and data pipelines, this release brings us a long way to making that a reality.

If you aren't already familiar with Atmo, it is an open source platform for building powerful and scalable server applications using WebAssembly. You can learn more from our comprehensive documentation and you can read about the last beta as well.

GraphQL

To kick things off, let's take a look at the newest capability to be added to the Runnable API, which is the ability for the functions in your Atmo project to make GraphQL requests:

impl Runnable for RsGraqhql {
    fn run(&self, _: Vec<u8>) -> Result<Vec<u8>, RunErr> {
        let result = match graphql::query("https://api.github.com/graphql", "{ repository (owner: \"suborbital\", name: \"reactr\") { name, nameWithOwner }}") {
            Ok(response) => {
                log::info(util::to_string(response.clone()).as_str());
                response
            }
            Err(e) => {
                error(e.message.as_str());
                return Err(RunErr::new(400, e.message.as_str()))
            }
        };

        Ok(result)
    }
}

With its explosion in popularity, it's really convenient to have GraphQL built in. Companies like GitHub and Shopify have added full GraphQL support to their APIs, so it's an easy way to access data from external services that exactly matches what you need to accomplish in your application.

Authentication

With several different methods of connecting your Runnables to external services, we need a way to securely authenticate those requests. Atmo Beta-3 includes a new authentication configuration to help your applications securely access third-party services. You can configure it in your Directive.yaml:

authentication:
  domains:
    api.github.com:
      headerType: bearer
      value: env(GITHUB_TOKEN)

This configuration allows Atmo to inject authentication into your Runnable's GraphQL and HTTP requests at runtime, which means sensitive information such as API tokens aren't given to the code running inside the WebAssembly sandbox. This security model is an important aspect of what makes Atmo special; it takes every measure to ensure your code is secure by design. By inserting the Authorization request header, secrets are managed by the runtime instead of the application code.

Streams

From the beginning, it was intended that Atmo would be able to handle several different input types beyond just HTTP requests. Beta-3 brings the new concept of stream handlers, which is Atmo's second input type. Streams open up a whole new world of possibilities including using Atmo in systems that use the actor pattern, messaging- and stream-based communication platforms, and more. Let's take a look:

handlers:

  - type: stream
    source: nats
    resource: user.login
    steps:
      - fn: record-login-event
      - fn: send-login-email
    respondTo: user.login-completed

This handler shows Atmo becoming an actor in a NATS -based system, and Beta-3 also supports websockets. A stream is comprised of messages that Atmo handles by executing the steps you define. This is incredibly powerful for building scalable distributed systems, as it allows Atmo to listen in on event and message streams, execute your Runnables, and then send responses if desired. The source and respondTo handler fields are new in Beta-3, and they allow your handler to become a flexible part of your distributed architecture. You can even describe an entire stream-based application in your Directive!

Connections

This release also includes the new connections configuration section in Directive.yaml. As alluded to in the stream handler example above, you can now direct Atmo to connect to external resources as part of your application definition, and it will make those connections available to use in other parts of your app:

connections:
  nats:
    serverAddress: nats://localhost:4222

By defining your app's external connection requirements declaratively in Directive.yaml, you can vastly simplify what it takes to set up a complex system. Just define what you need, and Atmo will make it so!

make-it-so.jpg

This release includes the usual barrage of under-the-hood improvements and fixes. Beta-4 is already underway, and it will include more types of connections such as Redis, Kafka, and Ockam, granular control over Runnable API capability access, and a whole bunch more. We're really proud of how far Atmo has come, and we're incredibly excited about what's on the horizon! The Suborbital team is growing, and we're really grateful that we get the chance to build a software platform based on cutting-edge technology that can power new paradigms and make existing systems more secure and performant.

Join the Suborbital Launch Pad newsletter below to get updates about Atmo, WebAssembly on the server, and awesome cloud native tech!

Cover photo by Eugene Kuznetsov from Unsplash