fbpx

faastRuby Local Documentation

faastRuby Local

NOTE: This document is under construction.

faastRuby Local is the tool you need to develop, test and deploy function-based applications to the faastRuby Cloud Platform. It simulates the faastRuby Cloud Platform, allowing you to run and debug your functions locally.

This document describes its features, components, and usage.

Features

Automatic detection of new Ruby and Crystal functions

When you create a folder inside the functions folder and add a file named handler.rb or handler.cr to it, faastRuby Local will detect that you want to create a function and initialize both handler and faastruby.yml for you, with automatic language detection.

Live compilation of Crystal functions

When you use Crystal functions in your app, faastRuby Local will trigger a compile action every time you make a change to their files, so you all you have to do is write code and hit ⌘+R or CTRL+R in the Browser 😉.

Real-time deploy to the cloud

With the Sync Mode enabled, faastRuby Local will automatically deploy your changes to a cloud workspace in real-time, as you modify your files. You can keep that ⌘+R or CTRL+R going, but now in the cloud!

Support for static assets

Projects have a public directory where you can put static files. They are automatically deployed when Sync Mode is enabled.

Components

faastRuby Local has 2 components: HTTP Server and Watchdog.

HTTP server

The HTTP server simulates the faastRuby Cloud Platform and allows you to run your functions locally. The goal is 99.9% compatibility, meaning that if your functions work locally, they will work in the cloud 99.9% of the time.

There are 2 main differences between Local and the Cloud Platform. In the cloud, you have no write permissions to the disk, and the TMP space you can use to manipulate files is capped at 5MB. Keep that in mind until we can reproduce those limits on faastRuby Local - we are working on it. For now, make sure your functions don't write large files to TMP and don't try writing files to the disk, because those will fail in the cloud. You can use a test cloud workspace by starting Local with Sync Mode enabled. More on that later on.

When you start Local, the HTTP server will be listening on http://localhost:3000.

Watchdog

The WatchDog watches for changes in your project's folder and performs tasks based on the developer's actions. For example, when you add a file named handler.rb to a folder inside your project's the functions directory, the Watchdog will assume you are trying to create a Ruby function and initialize it for you - configuration file and all. The same is valid for Crystal functions: create a file functions/some-function/handler.cr and the Watchdog will initialize a Crystal function for you and activate the live-compiling feature.

The live-compiling feature will do as its name says: it will compile your Crystal functions every time you make changes to any of its files.

Here is a graphical representation of how Watchdog works:

Sync Mode

If you start faastRuby Local with the option --sync, Watchdog will connect your local development environment to a Cloud Workspace and automatically deploy your functions and static assets in real-time as you make changes to them.

Developing applications with faastRuby Local

You can use faastRuby Local to develop, test and deploy APIs or fully featured Web Applications. Let's start with a Project.

Project

A Project is a set of functions that form an application, plus any static assets you might have (javascript, css, images, etc). To create a project, use the new-project command.

To create a project, use the new-project command.

~$ faastruby new-project myproject

This command will create a directory and initialize an application inside of it. The default template is for a web app. If you want to start an API, use --api.

~$ faastruby new-project myproject --api

The if you are building a web app, the newly created directory will look similar to this:

myproject
├── functions  <- Put your functions inside this directory
│   ├── catch-all <- This function will run when when a function is not found
│   │   ├── 404.html
│   │   ├── faastruby.yml
│   │   └── handler.rb
│   └── root  <- This function will run when a request ie made to the root path '/'
│       ├── faastruby.yml
│       ├── handler.rb
│       ├── index.html.erb
│       └── template.rb
├── public  <- Put static files inside this folder
│   ├── assets
│   │   ├── images
│   │   │   ├── background.png
│   │   │   └── ruby.png
│   │   ├── javascripts
│   │   │   └── main.js
│   │   └── stylesheets
│   │       └── main.css
│   ├── faastruby.yml  <- Static files configuration
│   └── favicon.ico
├── .gitignore  <- Ignores 'secrets.yml'
├── project.yml  <- Project configuration file
└── secrets.yml  <- Put your secrets here (more to it later on this doc)

Let's take a look at the default project configuration file:

project:
  # The project name
  name: myproject
  # The project identifier is used to ensure your workspaces will have unique names.
  # This is not a secret, but don't lose it!
  identifier: 123abc

  ## The 'public' directory, where you put static files.
  ## Files will be served from here first, meaning that if
  ## you have a function at '/product' and a folder '/product'
  ## inside the public folder, the public one will take precedence.
  ## Defaults to 'public'.
  # public_dir: public

  ## The name of the folder containing your functions. Defaults to 'functions'
  # functions_dir: functions

  ## The name of the function that will respond to requests made
  ## to '/'. Defaults to 'root'
  # root_to: root

  ## The setting 'catch_all' allows you to capture requests to
  ## non-existing functions and send them to another function.
  ## This is useful for setting custom 404 pages, for example.
  ## Defaults to 'catch-all'.
  # catch_all: catch-all

Workspaces

A project can have many Workspaces. When you deploy a project to the cloud platform, its functions and static files live in a Workspace. The workspace's name is a combination of the project's name, current environment and the project's identifier (that's why you can't lose this identifier). Using the example project above, when working on the environment stage, the workspace name will be myproject-stage-123abc.

Environments

Think of Environments as a string that you add to a workspace name in order to get the project deployed to different workspaces. If you call the production environment prod, the workspace name, still using the example above, will be myproject-prod-123abc. If your team works with features branches, you can use the branch name as environment name to create different workspaces in the cloud platform.

Functions

A function is a self-contained unit of work. They should be designed to do one thing very well, run very fast and require as little dependencies as possible.

The smallest function possible is made of two different files:

  • The function handler - handler.rb for Ruby or handler.cr for Crystal. The file must define a method called handler, and take one argument event. This method must render a response or render_nothing.
  • faastruby.yml - the function's configuration file. More on that later on.

Example:

# handler.rb
require 'json'
def handler(event)
  render json: {'Hello' => 'World'}.to_json
end
# faastruby.yml
cli_version: 0.5.12
name: ruby
runtime: ruby:2.6.2

The functions directory

By default, your project's functions will live inside a directory called functions. You can change this by editing the project's configuration file (project.yml).

The public directory

By default, your project's static files will live inside a directory called public. You can change this by editing the project's configuration file (project.yml).

Starting faastRuby Local

It is important that all development is done with faastRuby Local running. That's because Watchdog will be there to assist you, and make the experience of creating and testing your functions a breeze.

To start faastRuby Local, cd into the project's root directory and run:

~/myproject$ faastruby local

Then visit http://localhost:3000. You should see a welcome screen like this:

Using Sync Mode to automatically deploy your changes to the cloud

If you start faastRuby Local with the option --sync, Watchdog will connect your development environment with to a cloud workspace, and all changes you make on your code will be deployed to the cloud in real-time. To use this feature, stop Local and start it again with the following command:

~/myproject$ faastruby local --sync

Managing secrets

If you need to use secrets in your functions, you can define them inside the file secrets.yml, in your project's root directory. You have to define secrets per function per environment, as follows:

secrets:
  # SYNTAX
  # environment_name:
  #   function_name:
  #     secret_name: value
  #   another/function:
  #     another_secret: another_value
  stage:
    root:
      token: bfe76f4557ffc2de901cb24e0f87436f
    lists/pets:
      another_secret: PETSPETS
  prod:
    root:
      token: DontCommitThisFile
    lists/pets:
      another_secret: MakeSureThisFileIsOnDotGitignore

The secrets are stored with strong encryption in the database, decrypted on-the-fly and handed to your functions on each request. After the execution is finished, the secrets are wiped from memory.

To remove a secret from the cloud, just remove it from the file.

Using Gems in your functions

If a given function requires a gem, all you have to do is create a Gemfile inside of the function's directory.

For example, say you have a function name foo/bar. With Local running, create the file functions/foo/bar/Gemfile and Watchdog will initialize the Gemfile for you. Every time you save that file, Watchdog will run bundle install automatically, and deploy your function if you started Local with the argument --sync.

Then just require the gem normally in your code:

# Gemfile
source 'https://rubygems.org'

gem 'jwt'

group :test do
  gem 'rspec'
end
require 'jwt'

def handler(event)
  ...
end