# Welcome to AssemblyLift

Hello! Welcome to the AssemblyLift documentation.

AssemblyLift is an **open platform** for building [serverless](/resources/the-lexicon#serverless) cloud applications, with an emphasis on ease-of-use and safety.

The platform currently consists of:

* The AssemblyLift CLI
* The AssemblyLift Runtime
* The AssemblyLift IO Module Registry
* The AssemblyLift Rust Language SDK

The AssemblyLift Runtime is powered by the open-source [Wasmer Runtime](https://wasmer.io/), which provides an execution environment for [WebAssembly](https://webassembly.org) (WASM).

Using WASM means we can theoretically write our applications in any programming language which can be compiled to WASM (and use a common, consistent runtime for each). Currently the [Rust programming language](https://rust-lang.org) is supported, but more are to follow.&#x20;

## How It Works

![](/files/-MfdSdy_au0oZKNyWHS6)

1. Write applications in [TOML](/learn-assemblylift/getting-started#project-structure) and Rust
2. Compile your code to Terraform HCL and WebAssembly [with the AssemblyLift CLI](/learn-assemblylift/how-to-build)
3. Use the AssemblyLift CLI to deploy the infrastructure, runtime, and compiled WASM [with a single command](/learn-assemblylift/how-to-deploy)


# Getting Started

## Installing

### Prerequisites

AssemblyLift currently requires that you have the Rust toolchain installed. The easiest way to do this is via [rustup](https://rustup.rs/). In addition to the "default" toolchain targeting your system, you will also need to install the wasm32 toolchain with `rustup toolchain install wasm32-unknown-unknown`.

### Installing the CLI

AssemblyLift provides a Command Line Interface (CLI) called `asml`. The CLI is primarily responsible for building & deploying your application.

You can install `asml` using `cargo` with:

```
$ cargo install assemblylift-cli
```

Running `asml help` will print the CLI version, as well as a list of commands:

```
$ asml help
asml 0.3.0

USAGE:
    asml [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    bind    Bind the application to the cloud backend
    burn    Destroy all infrastructure created by 'bind'
    cast    Build the AssemblyLift application
    help    Prints this message or the help of the given subcommand(s)
    init    Initialize a basic AssemblyLift application
    make    Make a new service or function
    pack    Pack artifacts for publishing
    push    Push artifacts to a registry
    user    User authentication & information
```

## Getting an AWS Account

The default infrastructure provider for AssemblyLift is AWS Lambda + API Gateway, which require an [Amazon AWS](https://aws.amazon.com/) account.

[Creating an account](https://portal.aws.amazon.com/billing/signup#/start) is free, and both AWS Lambda and Amazon API Gateway are [free tier eligible](https://aws.amazon.com/premiumsupport/knowledge-center/what-is-free-tier/).

## Hello World!

You can create a new project with the `init` command. This will scaffold a basic project structure with a single service, containing a single function.

```
$ asml init --name myapp
$ tree myapp
myapp
├── assemblylift.toml
└── services
    └── my-service
        ├── my-function
        │   ├── Cargo.toml
        │   └── src
        │       └── lib.rs
        └── service.toml
```

If you like, you can verify everything is working by building the project with `cast` and then deploying it with `bind`.&#x20;

### Project Structure

AssemblyLift projects and services are defined in [TOML](https://toml.io) documents called *manifests*. Each project must have a manifest at the project root called **assemblylift.toml**, and each service must have a manifest at the service root called **service.toml**.

Each function is stored in a sub-directory under the service directory. Function directories are structured according to the given programming language.


# Services

An overview of Services

Services are the main unit of organization in the AssemblyLift framework. Primarily, they serve as a logical grouping of related [functions](/learn-assemblylift/functions).

## Make a New Service

You can create a new service in an existing AssemblyLift application via the `make` command:

```
$ asml make service myservice
```

This will create a directory under `services/` named `myservice` containing a default `service.toml` manifest.

In order for a service to be recognized by `cast`, it must be listed in the application manifest `assemblylift.toml`.

{% code title="assemblylift.toml" %}

```
[project]
name = "my-amazing-project"

[services]
default = { name = "myservice" }
```

{% endcode %}

## The Service Manifest

Each service is defined by its manifest, `service.toml`.

{% code title="service.toml" %}

```
# Each service must have a service table
[service]
name = "service-name" # A name is required

# The API table contains functions and authorizers
[api.functions.function-id]
name = "function-name" # A name is required

[api.authorizers.authorizer-id]
auth_type = "type"

# The IOmod table defines service dependencies
[iomod.dependencies.dependency-id]
version = "x.x.x"
coordinates = "organization.namespace.name"
```

{% endcode %}

The service manifest defines the service's API, as well as an IOmods we wish to use in our service's functions. Each section of the service manifest is described in greater detail in the following sections.


# Functions

Defining a Function within a Service

Functions are defined inside the `api.functions` table within the service manifest.

```
[api.functions.function-id]
# The function name is required
name = "myfunction"

# The `http` param defines an HTTP API entry for the function
# `verb` is an HTTP verb such as GET or POST
# Path parameters are denoted inside curly braces "{}"
http = { verb = "GET", path = "/path/maybe/with/{parameter}" }

# The authorizer id refers to an authorizer defined in the same service
authorizer_id = "<id>"

# The timeout in seconds after which the function is terminated, regardless of whether it has completed.
timeout_seconds = 3

# The size of the function in MB. AWS Lambda scales the CPU allocation with this value.
size_mb = 512
```

The `authorizer_id` refers to the table ID within the service manifest of the authorizer you wish to attach.

```
[api.authorizers.my-auth]
type = "iam"

[api.functions.my-func]
authorizer_id = "my-auth"
```

Please see the next section on [Authorizers](/learn-assemblylift/services/authorizers) for further details.

## HTTP Functions

The default API provider is Amazon API Gateway. Each service has a corresponding gateway endpoint, and specifying an HTTP verb and path for your function will create the corresponding routes & integrations. You can view details such as the generated API URL in your AWS Console.


# Authorizers

Defining a Function Authorizer within a Service

Authorizers are defined in the `api.authorizers` table within the service manifest.

{% code title="service.toml" %}

```
[api.authorizers.iam]
auth_type = "iam"
# IAM authorizers take no parameters
```

{% endcode %}

To be of any use, an authorizer must be attached to a function (see `authorizer_id` in [Functions](/learn-assemblylift/services/functions)). The type of authorizer must also be supported by the API provider. At this time the default provider (AWS Lambda/APIGW) supports two types of authorization; IAM or JWT.

Authorizers protect only the publicly defined API of a function (such as an HTTP route); a Lambda function can still be invoked by other means (such as the AWS SDK).

{% hint style="warning" %}
Without an attached authorizer, your functions will be **publicly accessible via HTTP** if a route is defined. We recommend always using at least an IAM authorizer during development. Tools such as [Postman](https://www.postman.com/) will help you test protected routes.
{% endhint %}

{% code title="service.toml" %}

```
[api.authorizers.cognito]
auth_type = "JWT"
audience = ["client_id"]
issuer = "issuer_url"
scopes = ["claim1", "claim2", ...] # optional
```

{% endcode %}

The JWT type is used for authorizers such as Cognito or Auth0, which support JWT/OAuth authorization.


# IOmod Dependencies

Defining a dependency on an IO Module

IO Modules (IOmods) are defined in the `iomod.dependencies` table within the service manifest.

{% code title="service.toml" %}

```
[iomod.dependencies.s3]
coordinates = "akkoro.aws.s3"
version = "0.1.0"
```

{% endcode %}

IOmods are defined by coordinates in the format `organization.namespace.name` and a [semantic version](https://semver.org/). Occasionally these will be seen written together in the format `org.namespace.name@major.minor.patch` .

By default IOmods will be fetched from the public [IO Module registry](/learn-assemblylift/io-modules/registry) at **registry.assemblylift.akkoro.io**. IOmod binaries can also be loaded from a local path, however this is intended for IOmod development.

```
[iomod.dependencies.s3]
coordinates = "akkoro.aws.s3"
version = "0.1.0"
type = "file"
from = "/absolute/path/to/executable"
```

Further details on IO Modules can be found in its [dedicated chapter](/learn-assemblylift/io-modules).


# Functions

An overview of Functions

Functions are units of execution in the AssemblyLift framework. They are grouped into services, and are themselves structured according to the chosen language (e.g with Rust each function is a Cargo crate).

Each function is compiled to a WebAssembly module, compatible with the AssemblyLift ABI.

## Overview

An AssemblyLift Function is an executable containing a *handler*, which is the entrypoint of the Function (similar to a *main* method in a regular application). A Function usually receives some input which is passed to the handler as an argument; the shape of this input will depend on the Function. The Function should return by indicating either success or an error to the runtime, though the Function is not required to return any specific data.

Functions which are invoked by an HTTP API for example, will receive input data in the shape of an [API Gateway Event](https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/nodejs-apig/event.json) (assuming you are using the default AWS provider).

The input payload received by a Function **must** be represented as [JSON](https://www.json.org/json-en.html).

## Make a New Function

You can create a new function in an existing service with the `make` command:

```
$ asml make function myservice.myfunction
```

where `myservice` is the name of the service in which you would like to make the function named `myfunction`.


# Rust Functions

Authoring a Function in the Rust programming language

## Dependencies

An AssemblyLift function written in Rust is a [library crate](https://learning-rust.github.io/docs/a4.cargo,crates_and_basic_project_structure.html). It requires several crates to be imported, which provide the necessary plumbing to make our Rust crate an AssemblyLift function.&#x20;

When making a new function via `asml make` the generated `Cargo.toml` should have included these crates. However, you should also ensure that you are using the latest patch version of each.

{% code title="Cargo.toml" %}

```
[dependencies]
asml_core = { version = "0.2", package = "assemblylift-core-guest" }
assemblylift_core_io_guest = { version = "0.3", package = "assemblylift-core-io-guest" }
asml_awslambda = { version = "0.3", package = "assemblylift-awslambda-guest" }
```

{% endcode %}

The *core* crate provides the `GuestCore` trait, which defines an interface for communicating with the cloud runtime (logging, low-level success/error response, etc). This trait is implemented by `AwsLambdaClient` which is provided by the *awslambda* crate.

The *core-io* crate provides the IO system; this is AssemblyLift's `Future` execution system supporting async/await.

## Handler Definition

The *awslambda* crate provides a macro called `handler!` which wraps up all the details of initializing the module, and provides a concise entry point for our function.

The `handler!` macro exports a function called `handler` which provides the entry-point from the runtime host.&#x20;

{% hint style="warning" %}
Only one handler can be defined per function. Calling the handler! macro more than once will produce a compiler error.
{% endhint %}

{% code title="lib.rs" %}

```rust
extern crate asml_awslambda;

use asml_core::GuestCore;
use asml_awslambda::{AwsLambdaClient, LambdaContext};

// Input must implement serde Deserialize
type Input = ();

handler!(context: LambdaContext<Input>, async {
    // function code
    // supports .await
})
```

{% endcode %}

The `extern crate` statement is required to bring `static`s & `extern`s into scope which are defined in the crate.

The `context` value is accessible from within the function closure, and provides access to details of the function invocation, include the input payload and authorization data.

## Writing an HTTP Function

If your function has an HTTP API, your function input and output must be compatible with the providers' API Gateway (Amazon API Gateway by default).

The crate [`assemblylift_awslambda_guest`](https://docs.rs/assemblylift-awslambda-guest/0.3.0/assemblylift_awslambda_guest/) includes structs & macros for working with Amazon API Gateway.

{% code title="lib.rs" %}

```rust
extern crate asml_awslambda;

use asml_core::GuestCore;
use asml_awslambda::{ApiGatewayEvent, AwsLambdaClient, LambdaContext};

handler!(context: LambdaContext<ApiGatewayEvent>, async {
    let event: ApiGatewayEvent = context.event;
    
    // Do something with the event
    
    if (function_success) {
        let response = "OK"; // This can be any serde::Serialize-able value
        http_ok!(response);
    } else {
        http_error!("There was an error!");
    }
})
```

{% endcode %}


# IO Modules

AssemblyLift IO Modules (*IOmods*) are a system for providing asynchronous input and output (IO) to WebAssembly (WASM) modules.

## In Theory

At the core of each AssemblyLift function is a compiled WASM module. The WASM guest is executed by a runtime, and is isolated from the host environment. To allow access to services available to the host (such as the filesystem or networking), the AssemblyLift ABI provides the WASM guest an interface to run an IO call in an IOmod process at the registered coordinates (the *org*.*namespace*.*name* triplet).

![](/files/-MfG5SGLNxVCdxS7NVPa)

This is inspired by the approach taken by the [Haskell programming language to IO](http://learnyouahaskell.com/input-and-output). Haskell being a purely functional programming language, operations which change the state of the world (i.e. which have *side-effects*) must specially handled. Haskell has the concept of *I/O Actions* which separates the side-effect code from the pure-function code.&#x20;

AssemblyLift IOmods follow the same paradigm, where our WASM modules are disallowed from having side-effects by design. Said another way, AssemblyLift considers that a WASM module is a pure function.

The AssemblyLift "Threader" runtime tracks the completion status of IOmod calls and manages the flow of data between IOmods and the WASM guest.

## In Practice

IO Modules are distributed in packages containing a manifest & an executable binary entrypoint. Functions in each service share the same set of IOmods as dependencies. When the AssemblyLift runtime starts, it first spawns all IOmods distributed with the service; each then registers itself with the runtime at the start of execution.

Each IOmod should also distribute a guest library for each supported guest programming language. These libraries wrap the low-level RPC code used to communicate with an IO Module in an API idiomatic to the language.

For example if you specify `akkoro.aws.s3` as a dependency in your service, a function written in Rust will interact with it by importing the `assemblylift-iomod-s3-guest` crate.


# Registry

AssemblyLift IO Modules are (by default) fetched from the IOmod Registry, located at **registry.assemblylift.akkoro.io**. The registry is read-only for the time being, while any early bugs or issues are ironed out.

Currently there is no registry search or UI (coming soon!). In the meantime, available modules are listed below.

| Coordinates         | Latest Version | Description                                        | Guest Crate                                                                                                                     |
| ------------------- | -------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| akkoro.aws.dynamodb | 0.1.5          | AWS DynamoDB Client. Generated against latest API. | [assemblylift-iomod-dynamodb-guest](https://docs.rs/assemblylift-iomod-dynamodb-guest/0.1.7/assemblylift_iomod_dynamodb_guest/) |
| akkoro.aws.lambda   | 0.1.1          | AWS Lambda Client. Generated against latest API.   | [assemblylift-iomod-lambda-guest](https://docs.rs/assemblylift-iomod-lambda-guest/0.1.1/assemblylift_iomod_lambda_guest/)       |
| akkoro.aws.s3       | 0.1.1          | AWS S3 Client. Generated against latest API.       | [assemblylift-iomod-s3-guest](https://docs.rs/assemblylift-iomod-s3-guest/0.1.1/assemblylift_iomod_s3_guest/)                   |
| akkoro.std.crypto   | 0.1.2          | Standard cryptography                              | [assemblylift-iomod-crypto-guest](https://docs.rs/assemblylift-iomod-crypto-guest/0.1.2/assemblylift_iomod_crypto_guest/)       |
| akkoro.std.http     | 0.1.0          | Standard HTTP client                               | [assemblylift-iomod-http-guest](https://docs.rs/assemblylift-iomod-http-guest/0.1.0/assemblylift_iomod_http_guest/)             |


# User Terraform

Adding a directory in the project root named `user_tf` and placing a Terraform/HCL file in it will cause this directory to be included in the AssemblyLift build as a module. This functionality can be used to extend the application with additional infrastructure not yet supported natively by AssemblyLift.

Examples TODO 🚧​


# Providers

TODO 🚧​


# How to Build

AssemblyLift applications are built using the `cast` command:

```
$ asml cast
```

This command will compile each function in each service using the language's build tool, and then compile the resulting WASM to backend-native binary.

In addition, `asml` will invoke [Terraform](/resources/the-lexicon#terraform) & generate an infrastructure plan for your project. All build artifacts are serialized to the `net` directory.

## Configuring Remote State

AssemblyLift allows you to configure the S3/DynamoDB [remote state store](https://www.terraform.io/docs/language/state/remote.html) in the AssemblyLift manifest.

{% code title="assemblylift.toml" %}

```
[project]
name = "my-project"

# The terraform table is optional
# By default Terraform will write state to a local file
[terraform]
state_bucket_name = "bucket"
lock_table_name = "table"
```

{% endcode %}

This configuration requires that the bucket & table resources referenced by `state_bucket_name` and `lock_table_name` already exist and are correctly configured.

## Using an AWS Credentials Profile

If you are deploying to multiple AWS accounts, the `asml` CLI will respect the setting of the `AWS_PROFILE` environment variable. For example:

```
$ export AWS_PROFILE=my-profile-name
$ asml cast
$ asml bind
```


# How to Deploy

AssemblyLift applications are deployed using the `bind` command:

```
$ asml bind
```

This command will bind the structure in `net/` (generated by [cast](/learn-assemblylift/how-to-build)) to your chosen backend.


# Design Pillars

### Adherence to Best Practices

AssemblyLift is designed to generate and manage [serverless](/resources/the-lexicon#serverless) infrastructure on your behalf. You may have used tools such as this in the past. If so, you may have found what was deployed a little naive architecturally, especially over time as your application grows.

AssemblyLift is what is sometimes referred to as an *opinionated* framework. That is to say, that it has a prescribed way of doing things and does not leave all architectural decisions to the user.

To this end, AssemblyLift abstracts away the underlying cloud provider (AWS Lambda for example) and provides an application model based on [services](/learn-assemblylift/services) and [functions](/learn-assemblylift/functions). AssemblyLift takes care of fitting this model to the selected provider, according to that provider's best practices. For example, deployment to AWS Lambda makes use of Lambda layers to reduce the deployment size of functions.

### High Efficiency

WebAssembly is known for providing high-performance execution, relative to an interpreted language such as Python or a VM-based language like Java. AssemblyLift uses [Wasmer](https://wasmer.io) internally to pre-compile WASM to a native binary, and to execute the binary later at near-native performance.

AssemblyLift also does its best to minimize the size of the deployed code, as well as the memory used by the runtime. For example, AWS Lambda functions are [priced](https://aws.amazon.com/lambda/pricing/) in *Gigabyte-seconds*; that is, the more memory your function is allocated the more you will be charged. Lambda will also scale the number of allocated vCPUs linearly with the allocation of memory. Keeping the memory footprint of the AssemblyLift runtime small therefore enables more computation per second for the same price. Where performance is less of a concern, this enables you to use very small memory allocations -- as little as 128MB in some cases, which is nearly *8x* cheaper than the AssemblyLift default of 1024MB.

### Safer Execution

The entire AssemblyLift runtime is written in Rust, which helps prevent several kinds of bugs & vulnerabilities due to its memory-safe & thread-safe design.

WebAssembly modules are isolated by design; they provide no means to communicate with their host or any network, and they are unable to allocate memory anywhere but their own linear memory.

AssemblyLift provides WASM modules with connectivity via [IOmods](/learn-assemblylift/io-modules); themselves external processes which communicate with the modules via remote procedure calls (RPC).


# The Lexicon

"Wait, what?" A glossary of jargon.

## Serverless

*Serverless computing* or just *serverless* is a cloud computation model built around the idea of on-demand, ephemeral computing. A typical characteristic is that you pay only for exactly what you use, often to the millisecond.

Not to be confused with the *Serverless framework*, another tool for developing serverless apps.

## Terraform

[Terraform](https://terraform.io) is an infrastructure-as-code tool by [HashiCorp](https://hashicorp.com). AssemblyLift uses Terraform internally to manage infrastructure.


# Welcome to AssemblyLift

Hello, world! Welcome to AssemblyLift.

AssemblyLift is a framework for building [serverless](/master/resources/the-lexicon#serverless) cloud applications. The framework deploys apps on top of a runtime powered by [WebAssembly](https://webassembly.org).

WebAssembly (WASM) means we can write our applications in any programming language which can be compiled to WASM; currently the [Rust programming language](https://rust-lang.org) is supported, but more are to follow.

## Goals

### Adherence to Best Practices

AssemblyLift is designed to generate and manage [serverless](/master/resources/the-lexicon#serverless) infrastructure on your behalf. You may have used tools such as this in the past. If so, you may have found what was deployed a little naive architecturally, especially over time as your application grows.

AssemblyLift is what is sometimes referred to as an *opinionated* framework. That is to say, that it has a prescribed way of doing things and does not leave all architectural decisions to the user.

To this end, AssemblyLift abstracts away the underlying cloud backend (AWS Lambda for example) and provides an application model based on [services](/master/learn-assemblylift/untitled) and [functions](/master/learn-assemblylift/functions). AssemblyLift takes care of fitting this model to the selected backend, according to that backend's best practices. For example, deployment to AWS Lambda makes use of Lambda layers to reduce the deployment size of functions.

### High Efficiency

WebAssembly is known for providing high-performance execution, relative to an interpreted language such as Python or a VM-based language like Java. AssemblyLift uses [Wasmer](https://wasmer.io) internally to pre-compile WASM to a backend-native binary, and to execute the binary later at near-native performance.

AssemblyLift also does its best to minimize the size of the deployed code, as well as the memory used by the runtime. For example, AWS Lambda functions are [priced](https://aws.amazon.com/lambda/pricing/) in *Gigabyte-seconds*; that is, the more memory your function is allocated the more you will be charged. Lambda will also scale the number of allocated vCPUs linearly with the allocation of memory. Keeping the memory footprint of the AssemblyLift runtime small therefore enables more computation per second for the same price. Where performance is less of a concern, this enables you to use very small memory allocations -- as little as 128MB in some cases, which is nearly *8x* cheaper than the default of 1024MB.

### Strong Isolation

The entire AssemblyLift runtime is written in Rust, which helps prevent several kinds of bugs & vulnerabilities due to its memory-safe & thread-safe design.

WebAssembly modules are isolated by design; they provide no means to communicate with their host or any network, and they are unable to allocate memory anywhere but their own linear memory.

AssemblyLift provides WASM modules with connectivity via IOmods; themselves external processes which communicate with the modules via remote procedure calls (RPC).


# Getting Started

## Installing

AssemblyLift provides a Command Line Interface (CLI) called `asml`. The CLI is primarily responsible for building & deploying your application.

{% hint style="info" %}
The AssemblyLift CLI delegates to language-specific tools for compilation. For example, writing functions with Rust will require that you have installed Cargo.
{% endhint %}

You can install `asml` using `cargo` with:

```
$ cargo install assemblylift-cli
```

Running `asml help` will print the CLI version, as well as a list of commands:

```
$ asml help
asml 0.2.9

USAGE:
    asml [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    bind    Bind the application to the cloud backend
    burn    Destroy all infrastructure created by 'bind'
    cast    Build the AssemblyLift application
    help    Prints this message or the help of the given subcommand(s)
    init    Initialize a basic AssemblyLift application
    make    Make a new service or function
```

## Hello World!

You can create a new project with the `init` command. This will scaffold a basic project structure with a single service, containing a single function.

```
$ asml init --name myapp
$ tree myapp
myapp
├── assemblylift.toml
└── services
    └── my-service
        ├── my-function
        │   ├── Cargo.toml
        │   └── src
        │       └── lib.rs
        └── service.toml
```

If you like, you can verify everything is working by building the project with `cast` and then deploying it with `bind`.&#x20;


# Services

Services are the main unit of organization in the AssemblyLift framework. Primarily, they serve as a logical grouping of related [functions](/master/learn-assemblylift/functions).

## Make a New Service

You can create a new service in an existing AssemblyLift application via the `make` command:

```
$ asml make service myservice
```

This will create a directory under `services/` named `myservice` containing a default `service.toml` manifest.

In order for a service to be recognized by `cast`, it must be listed in the  application manifest `assemblylift.toml`.

{% code title="assemblylift.toml" %}

```
[project]
name = "my-amazing-project"
version = 0.0.0

[services]
default = { name = "myservice" }
```

{% endcode %}


# Functions

Functions are units of execution in the AssemblyLift framework. They are grouped into services, and are themselves structured according to the chosen language (e.g with Rust each function is a Cargo crate).

Each function is compiled to a WebAssembly module, compatible with the AssemblyLift ABI.

## Make a New Function

You can create a new function in an existing service with the `make` command:

```
$ asml make function myservice.myfunction
```

where `myservice` is the name of the service in which you would like to make the function named `myfunction`.

## Defining an API

AssemblyLift functions can be exposed via an HTTP API. When using the AWS Lambda backend, this API is deployed to [Amazon API Gateway](https://aws.amazon.com/api-gateway/).

{% code title="service.toml" %}

```
[service]
name = "myservice"

[api.functions.myfunction]
name = "myfunction"
http = { verb = "GET", path = "/" }
```

{% endcode %}

You define an API for a function using the `http` field, which accepts `verb` and `path`.

## Defining an Authorizer

AssemblyLift supports defining authorizers and attaching them per-function. Authorizers *require* an HTTP API to be defined for the function.

The Lambda backend currently supports IAM and JWT authorizers.

{% code title="service.toml" %}

```
[service]
name = "myservice"

[api.functions.myfunction]
name = "myfunction"
http = { verb = "GET", path = "/" }
authorizer_id = "cognito"

[api.authorizers.cognito]
auth_type = "JWT"
audience = ["clientid"]
issuer = "https://cognito-idp.us-east-1.amazonaws.com/myuserpoolid"
```

{% endcode %}


# Rust Functions

## Dependencies

An AssemblyLift function written in Rust is a [library crate](https://learning-rust.github.io/docs/a4.cargo,crates_and_basic_project_structure.html). It requires several crates to be imported, which provide the necessary plumbing to make our Rust crate an AssemblyLift function.&#x20;

When making a new function via `asml make` the generated Cargo.toml should have included these crates. However, you should also ensure that you are using the latest patch version of each.

{% code title="Cargo.toml" %}

```
[dependencies]
asml_core = { version = "0.2", package = "assemblylift-core-guest" }
asml_core_io = { version = "0.2", package = "assemblylift-core-io-guest" }
asml_awslambda = { version = "0.2", package = "assemblylift-awslambda-guest" }
```

{% endcode %}

The *core* crate provides the `GuestCore` trait, which defines an interface for communicating with the cloud runtime (logging, low-level success/error response, etc). This trait is implemented by `AwsLambdaClient` which is provided by the *awslambda* crate.

The *core-io* crate provides the IO system; this is AssemblyLift's `Future` execution system supporting async/await.

## Handler Definition

The *awslambda* crate provides a macro called `handler!` which wraps up all the details of initializing the module, and provides a concise entry point for our function.

The `handler!` macro exports a function called `handler` which provides the entry-point from the runtime host.&#x20;

{% hint style="warning" %}
Only one handler can be defined per function. Calling the handler! macro more than once will produce a compiler error.
{% endhint %}

{% code title="lib.rs" %}

```rust
extern crate asml_awslambda;

use asml_core::GuestCore;
use asml_awslambda::{AwsLambdaClient, LambdaContext};

handler!(context: LambdaContext<ApiGatewayEvent>, async {
    // function code
    // supports .await
})
```

{% endcode %}

The `extern crate` statement is required to bring `static`s & `extern`s into scope which are defined in the crate.

The `context` value is accessible from within the function code, and provides access to details of the function invocation, include the input payload and authorization data.


# How to Build

AssemblyLift applications are built using the `cast` command:

```
$ asml cast
```

This command will compile each function in each service using the language's build tool, and then compile the resulting WASM to backend-native binary.

In addition, `asml` will invoke [Terraform](/master/resources/the-lexicon#terraform) & generate an infrastructure plan for your project. All build artifacts are serialized to the `net` directory.


# How to Deploy

AssemblyLift applications are deployed using the `bind` command:

```
$ asml bind
```

This command will bind the structure in `net/` (generated by [cast](/master/learn-assemblylift/how-to-build)) to your chosen backend.


# The Lexicon

"Wait, what?" A glossary of jargon.

## Serverless

*Serverless computing* or just *serverless* is a cloud computation model built around the idea of on-demand, ephemeral computing. A typical characteristic is that you pay only for exactly what you use, often to the millisecond.

Not to be confused with the *Serverless framework*, another tool for developing serverless apps.

## Terraform

[Terraform](https://terraform.io) is an infrastructure-as-code tool by [HashiCorp](https://hashicorp.com). AssemblyLift uses Terraform internally to manage infrastructure.


