Rust Builder (@now/rust)

Status: Beta

This Builder takes in a Rust program and outputs it as a Lambda.

When to Use It

Whenever you want to expose an API or a function written in Rust.

How to Use It

Define an index.rs file inside a folder as follows:

use http::{Request, Response, StatusCode, header};

fn handler(request: Request<()>) -> http::Result<Response<String>> {
    let response = Response::builder()
        .status(StatusCode::OK)
        .header(header::CONTENT_TYPE, "text/html")
        .body("<!doctype html><html><head><title>A simple deployment with Now!</title></head><body><h1>Welcome to Rust on Now</h1></body></html>".to_string())
        .expect("failed to render response");

    Ok(response)
}

Define a Cargo.toml like so:

[package]
name = "rust-project"
version = "0.1.0"
edition = "2018"

[dependencies]
http = "0.1"

A Cargo.toml file defining the Rust dependencies.

Note: Your Cargo.toml file should contain the Rust crates used in your application.

And define a now.json like:

{
  "name": "rust-project",
  "version": 2,
  "builds": [
    {
      "src": "index.rs",
      "use": "@now/rust"
    }
  ]
}

A now.json file defining the Now platform version and a build step using the @now/rust Builder.

The example above can be seen live at https://rust-kit-rm1x19uq8.now.sh/.

Also, the source code of the deployment can be checked by appending /_src e.g. https://rust-kit-rm1x19uq8.now.sh/_src.

Technical Details

Entry Point

The entry point file can either be a .rs source file or a Cargo.toml file.

.rs Entry Point

When you use one or multiple .rs files as an entry point for this Builder, Now will setup the serverless environment for you.

The requirements for this entry point is to expose a handler function and not to have a main function.

The example for the "How to Use It" section uses this method.

If a Cargo.toml exists in the project relating to the entry point, the dependencies will be installed for the Rust project.

Cargo.toml Entry Point

When using a Cargo.toml file as an entry point for this Builder, Now will use cargo read-manifest to build each binary within the project.

This entry point method is an advanced method of using this Builder and requires Rust files to assemble their own runtimes.

Defining a Cargo.toml file as an entry point requires a Rust file at src/main.rs or files defined as a [[bin]]` target.

An example src/main.rs Rust file within a project including a Cargo.toml file acting as the entry point:

use http::{StatusCode, header};
use now_lambda::{error::NowError, lambda, IntoResponse, Request, Response};
use std::error::Error;

fn handler(request: Request) -> Result<impl IntoResponse, NowError> {
    let uri = request.uri();
    let response = Response::builder()
        .status(StatusCode::OK)
        .header(header::CONTENT_TYPE, "text/html")
        .body(format!(
            "You made a request to the following URL: {}",
            uri
        ))
        .expect("failed to render response");

    Ok(response)
}

// Start the runtime with the handler
fn main() -> Result<(), Box<dyn Error>> {
    Ok(lambda!(handler))
}

This requires one dependency, with the example above using another dependency, http.

The required dependency is now_lambda which provides all of the resources needed to provide the serverless runtime.

The Cargo.toml entry point for the example above is the following:

[package]
name = "rust-project"
version = "0.1.0"
edition = "2018"

[dependencies]
http = "0.1"
now_lambda = "*"

An example Cargo.toml entry point defining http and now_lambda dependencies.

Dependencies

This Builder supports installing dependencies defined in the Cargo.toml file.

Furthermore, more system dependencies can be installed at build time with the presence of a shell build.sh file in the same directory as the entry point file.

By default, openssl is installed by the Builder due to its common usage with Rust projects.

Rust Version

The version of Rust that this Builder supports is 1.31.1

Maximum Lambda Bundle Size

To help keep cold boot times low, the maximum output bundle size for a Rust lambda is, by default, 25mb. This limit is extendable up to 50mb.

Example maxLambdaSize configuration:
{
  "builds": [
    { "src": "*.rs", "use": "@now/rust", "config": { "maxLambdaSize": "40mb" } }
  ]
}

Resources

The goal of the ZEIT Docs is to provide you with all the information you need to easily deploy your projects. The following resources can also help you set up other projects: