An open API service indexing awesome lists of open source software.

https://github.com/ThinkR-open/mariobox

A Framework For Packaging {plumber} APIs
https://github.com/ThinkR-open/mariobox

Last synced: 6 months ago
JSON representation

A Framework For Packaging {plumber} APIs

Awesome Lists containing this project

README

        

---
output: github_document
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = " ",
fig.path = "man/figures/README-",
out.width = "100%"
)

cat_mariobox_yaml <- function(path_pipo) {
cat(
paste0(
readLines(
file.path(path_pipo, "inst/mariobox.yml")
),
"\n"
)
)
}
```

# {mariobox}

[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[![CRAN status](https://www.r-pkg.org/badges/version/mariobox)](https://CRAN.R-project.org/package=mariobox)
[![R-CMD-check](https://github.com/ThinkR-open/mariobox/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ThinkR-open/mariobox/actions/workflows/R-CMD-check.yaml)

[DISCLAIMER] This is a Work In Progress, please use at your own risk.

The goal of `{mariobox}` is to provide a framework for packaging {plumber} APIs.
Think of it as the "`{golem}` for `{plumber}`"

## Installation

You can install the development version of `{mariobox}` from [GitHub](https://github.com/) with:

``` r
# install.packages("remotes")
remotes::install_github("ThinkR-Open/mariobox")
```

## Example

```{r}
library(mariobox)
```

### Creating a new {mariobox} project:

```{r}
path_pipo <- tempfile(pattern = "pipo")

# The create mariobox function will generate a new prefilled project
# with everything you need to get your started
create_mariobox(
path = path_pipo,
open = FALSE
)
```

By default, you'll find the following structure:

```{r}
fs::dir_tree(path_pipo)
```

The default API comes with one default endpoint, `/health`, which returns a 200 with the "ok" text.

We've made the choice to organise your API inside a YAML, so that you can be as close as possible to a package structure.
`{mariobox}` will then do a little bit of its magic and parse this YAML to build the `{plumber}` API.

```{r, echo=FALSE}
cat_mariobox_yaml(path_pipo)
```

### Add/Remove endpoints

`{mariobox}` comes with a series of functions to add endpoints to your app.
The generic one is `add_endpoint`, that allows you to pass any HTTP verb, and add_get and friends are wrappers around this function.

```{r}
add_endpoint(
name = "allo",
method = "GET",
open = FALSE,
pkg = path_pipo
)
```

This will produce the following R file:

```{r echo = FALSE}
readLines(
file.path(
path_pipo,
"R/get_allo.R"
)
) |> cat(sep = "\n")
```

```{r}
add_get(
name = "hey",
open = FALSE,
pkg = path_pipo
)
```

```{r}
fs::dir_tree(path_pipo)
```

The YALML is automatically updated:

```{r, echo=FALSE}
cat_mariobox_yaml(path_pipo)
```

```{r}
remove_endpoint(
name = "allo",
method = "GET",
pkg = path_pipo
)
```

```{r}
fs::dir_tree(path_pipo)
```

The YALML is automatically updated:

```{r, echo=FALSE}
cat_mariobox_yaml(path_pipo)
```

### About endpoint functions

All endpoint functions will be in the following format:

```{r eval = FALSE}
METHOD_NAME <- function(req, res) {
METHOD_NAME_f()
}

METHOD_NAME_f <- function() {
return("ok")
}
```

where `METHOD` is the HTTP verb and `name` is the name you've set in your function.

This format might seem weird, but the idea is to separate the concerns in the following format:

+ METHOD_NAME() will handle the http elements (login, headers..)
+ METHOD_NAME_f() will be a standard function returning data.

That way, you can handle the data manipulation function just like a plain standard one, test it, interact with it, etc, without having to care about the HTTP part.

## Running the API

In dev, you can launch the file at dev/run_dev.R.
```{r eval = FALSE}
source("dev/run_dev.R", echo = TRUE)
```

In production, the `run_api()` is in charge of running the API.

If you want to deloy to RStudio Connect, the `build_plumber_file()` function will create a `plumber.R` file at the root of your folder. You can deploy using this file.

```{r}
build_plumber_file(pkg = path_pipo)
```

This will produce the following file:

```{r echo = FALSE}
readLines(
file.path(
path_pipo,
"plumber.R"
)
) |> cat(sep = "\n")
```