Serverless functions
ricochet
provides a serverless function runtime for R as the content type serverless-r
.
Serverless R enables users to create a simple R script with function definitions and deploy them as a RESTful API. The serverless function runtime abstracts away the hard work of converting R code into RESTful APIs so you can focus on deploying.
Usage
The serverless-r
content type requires an R script as the entrypoint which defines a list object called routes
. The routes
object is used to define the REST API endpoints.
Take an example hello-world.R
file:
hello_world <- function() {
"hello, world!"
}
add2 <- function(x, y) {
x + y
}
# alternatively specify per-route (de)serializers
routes <- list(add2, hello_world)
That's it! This will create a REST API with two routes: /add2
and hello_world
.
You can change the name of the endpoints by providing a named list. For example the route
routes <- list(
"add-2" = add2,
"hello-world" = hello_world
)
will create two endpoints called /add-2
and /hello-world
.
Deploying
To deploy a serverless-r
item, create a new _ricochet.toml
in your project using ricochet::use_ricochet_toml()
. When selecting prompted to select the content type "Serverless R"
. Then run ricochet::deploy()
. Thats it!
Request Types
The serverless R runtime supports only GET and POST requests. Function without any arguments are served as a GET
request. If a function has aguments, it is accessible via POST
request.
By default all responses return (serialized) JSON. POST requests expect JSON in their bodies by default.
Using (de)serializers
It is possible to customize the type that responses are serialized as and how bodies are deserialized. Below are the available serializers and deserializers.
- Serializers:
-
csv
,excel
,feather
,geojson
,html
,htmlwidget
,jpeg
,json
,json-unboxed
,octet
,parquet
,pdf
,png
,png
,svg
,svglite
,text
,tiff
,tsv
,yaml
.
-
- Deserializers:
-
csv
,excel
,feather
,form
,geojson
,json
,multi
,none
,octet
,parquet
,rds
,text
,tsv
,yaml
-
To customize the serialization and deserialization method, the routes
list uses a named list with structure:
list(
fn = fn_object, # required
serialize = "json-unboxed", # optional
deserialize = "json" # optional
)
Example
You can return a csv file from your serverless functions by specifying the serialize = "csv"
or you can also expect a csv file as your input by setting deserialize = "csv"
as well.
The below example creates two endpoints. /penguins
returns the first 5 rows of the penguins
data frame as a csv file and /nrow
returns the number of rows sent in a csv file request.
routes <- list(
penguins = list(
fn = \() penguins[1:5,],
serialize = "csv"
),
nrow = list(
fn = \(.df) nrow(.df),
deserialize = "csv"
)
)
The deployed serverless functions can be called using httr2. To read the csv file:
library(httr2)
request("https://ricochet.rs/{ID}/penguins") |>
req_perform() |>
resp_body_string() |>
readr::read_csv()
#> # A tibble: 5 × 8
#> species island bill_len bill_dep flipper_len body_mass sex year
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
#> 1 Adelie Torgersen 39.1 18.7 181 3750 male 2007
#> 2 Adelie Torgersen 39.5 17.4 186 3800 female 2007
#> 3 Adelie Torgersen 40.3 18 195 3250 female 2007
#> 4 Adelie Torgersen NA NA NA NA NA 2007
#> 5 Adelie Torgersen 36.7 19.3 193 3450 female 2007
To send a csv file and count the number of rows:
tmp <- tempfile(fileext = ".csv")
readr::write_csv(penguins[1:100,], tmp)
request("https://ricochet.rs/{ID}/nrow") |>
req_body_raw(brio::read_file(tmp)) |>
req_headers("Content-Type" = "text/csv") |>
req_perform() |>
resp_body_json()
#> [1] 100