You are on page 1of 2

REST APIs with plumber: : CHEAT SHEET

Introduction to REST APIs Plumber pipeline Running Plumber APIs


Web APIs use HTTP to communicate between client and server. Plumber endpoints contain R code that is executed in response to an Plumber APIs can be run programmatically
HTTP HTTP request. Incoming requests pass through a set of mechanisms from within an R session.
request before a response is returned to the client. Path to API definition
"
library(plumber)
HTTP
response
! FILTERS plumb("plumber.R") %>%
client server pr_run(port = 5762) Specify API
Filters can forward requests (a er potentially mutating them), throw port
HTTP is built around a request and a response. A client makes a errors, or return a response without forwarding the request. Filters
request to a server, which handles the request and provides a are defined similarly to endpoints using the @filter [name] This runs the API on the host machine supported by the current R
response. Requests and responses are specially formatted text tag. By default, filters apply to all endpoints. Endpoints can opt out session.
containing details and data about the exchange between client and of filters using the @preempt tag. IDE INTEGRATION
server. Publish API to
REQUEST PARSER RStudio Connect
Path
Parsers determine how Plumber parses the incoming request body. Create new
HTTP Method curl -v “http://httpbin.org/get”
By default Plumber parses the request body as JavaScript Object Plumber API
Notation (JSON). Other parsers, including custom parsers, are Run API in
#> GET / get HTTP/1.1 HTTP Version current R session
Headers #> Host: httpbin.org identified using the @parser [parser name] tag. All
#> User-Agent: curl/7.55.1 registered parsers can be viewed with registered_parsers().
#> Accept: */*
# ENDPOINT Documentation
# Request Body Plumber APIs automatically generate an OpenAPI specification file.
Message body Endpoints define the R code that is executed in response to This specification file can be interpreted to generate a dynamic
RESPONSE incoming requests. These endpoints correspond to HTTP methods user-interface for the API. The default interface is generated via
and respond to incoming requests that match the defined method. Swagger.
HTTP Version Status code
Reason phrase METHODS
#< HTTP/1.1 200 OK • @get - request a resource • @head - no request body Endpoint details
#< Connection: keep-alive • @post - send data in body • @options - describe options
Headers #< Date: Thu, 02 Aug 2018 18:22:22 GMT
# • @put - store / update data • @patch - partial changes
Parameter details Edit parameters
# Response Body • @delete - delete resource • @use - use all methods
Message body
SERIALIZER
Plumber: Build APIs with R Serializers determine how Plumber returns results to the client. By
Send request

Plumber uses special comments to turn any arbitrary R code into API default Plumber serializes the R object returned into JavaScript
endpoints. The example below defines a function that takes the msg Object Notation (JSON). Other serializers, including custom
argument and returns it embedded in additional text. curl command used to
serializers, are identified using the @serializer send request
[serializer name] tag. All registered serializers can be
Plumber @ decorators viewed with registered_serializers().
comments library(plumber) define API
begin with #* characteristics Filter name
Identify as library(plumber)

Interact with the API


#* @apiTitle Plumber Example API filter
#* @filter log
#* Echo back the input function(req, res) {
#* @param msg The message to echo Forward Once the API is running, it can be interacted with using any HTTP
print(req$HTTP_USER_AGENT)
#* @get /echo
/<path> is used to
request forward() client. Note that using httr requires using a separate R session
HTTP Method function(msg = "") { define the location } from the one serving the API.
list( of the endpoint Endpoint
msg = paste0( description #* Convert request body to uppercase (resp <- httr::GET("localhost:5762/echo?msg=Hello"))
"The message is: '", msg, "'") #* @preempt log #> Response [http://localhost:5762/echo?msg=Hello]
) Opt out of #> Date: 2018-08-07 20:06
Parser #* @parser json the log filter
} #* @post /uppercase #> Status: 200
#* @serializer json #> Content-Type: application/json
HTTP Method #> Size: 35 B
function(req, res) { Endpoint path
toupper(req$body) httr::content(resp, as = "text")
} #> [1] "{\"msg\":[\"The message is: 'Hello'\"]}"
Serializer

RStudio® is a trademark of RStudio, Inc. • CC BY SA RStudio • info@rstudio.com • 844-448-1212 • rstudio.com • Learn more at www.rplumber.io • plumber 1.1.0 • Updated: 2021-03

ft

Programmatic Plumber Advanced Plumber


Tidy Plumber REQUEST and RESPONSE ASYNC PLUMBER
Plumber is exceptionally customizable. In addition to using special Plumber provides access to special req and res objects that can Plumber supports asynchronous execution via
comments to create APIs, APIs can be created entirely programatically. be passed to Plumber functions. These objects provide access to the the future R package. This pattern allows
This exposes additional features and functionality. Plumber has a request submitted by the client and the response that will be sent to Plumber to concurrently process multiple
convenient “tidy” interface that allows API routers to be built piece by the client. Each object has several components, the most helpful of requests.
piece. The following example is part of a standard plumber.R file. which are outlined below:
library(plumber)
library(plumber) Use @plumber tag future::plan("multisession")
Name Example Description Set the execution
#* @get /slow plan
#* @plumber
req function() {
function(pr) { Function that accepts and
pr %>% modifies a plumber router promises::future_promise({
pr_get(path = "/echo", The Plumber router slow_calc()
req$pr plumber::pr() Slow calculation
handler = function(msg = "") { processing the request })
list(msg = paste0( }
"The message is: '", Typically the same as
“Tidy” functions req$body list(a=1)
for building out
msg, argsBody MOUNTING ROUTERS
"'")
Plumber API
) The parsed body Plumber routers can be combined by mounting routers into other
}) %>%
req$argsBody list(a=1)
output routers. This can be beneficial when building routers that involve
pr_get(path = "/plot", several di erent endpoints and you want to break each component
handler = function() {
req$argsPath list(c=3)
The values of the path out into a separate router. These separate routers can even be
rand <- rnorm(100) arguments separate files loaded using plumb().
hist(rand)
}, Create an initial
The parsed output from library(plumber) router
serializer = serializer_png()) %>% req$argsQuery list(e=5)
req$QUERY_STRING
pr_post(path = "/sum", route <- pr() %>%
handler = function(a, b) { pr_get("/foo", function() "foo")
as.numeric(a) + as.numeric(b) req$cookies list(cook = "a") A list of cookies
}) #* @plumber
} Mount one router
The method used for function(pr) { into another
req$REQUEST_METHOD "GET" pr %>%
OpenAPI the HTTP request
pr_mount("/bar", route)
Plumber automatically creates an OpenAPI specification file based on The path of the }
Plumber comments. This file can be further modified using req$PATH_INFO "/"
incoming HTTP request In the above example, the final route is /bar/foo.
pr_set_api_spec() with either a function that modifies the
existing specification or a path to a .yaml or .json specification file. All of the HTTP headers RUNNING EXAMPLES
req$HTTP_* "HTTP_USER_AGENT"
sent with the request Some packages, like the Plumber package itself, may include
library(plumber)
The raw() contents of example Plumber APIs. Available APIs can be viewed using
#* @param msg The message to echo reqe$bodyRaw charToRaw("a=1")
the request body available_apis(). These example APIs can be run with
#* @get /echo plumb_api() combined with pr_run().
function(msg = "") { res
list( Identify the
msg = paste0(
list(header = HTTP headers to library(plumber) package name and
"The message is: '", msg, "'") res$headers API name
) "abc") include in the response
plumb_api(package = "plumber",
}
Function that receives setHeader("foo", name = "01-append",
and modifies the existing res$setHeader() Sets an HTTP header edit = TRUE) %>%
#* @plumber "bar")
specification pr_run() Optionally open the
function(pr) { file for editing
pr %>% setCookie("foo", Sets an HTTP cookie on Run the example
res$setCookie() API
pr_set_api_spec(function(spec) { "bar") the client
spec$paths[["/echo"]]$get$summary <-
Removes an HTTP
Deploying Plumber APIs
"Echo back the input"
res$removeCookie removeCookie("foo")
spec cookie
}) Return the updated
} specification res$body "{\"a\":[1]}" Serialized output Once Plumber APIs have been
By default, Swagger is used to interpret the OpenAPI specification file developed, they o en need to be
and generate the user interface for the API. Other interpreters can be The response HTTP deployed somewhere to be useful.
used to adjust the look and feel of the user interface via
res$status 200
status code Plumber APIs can be deployed in a
pr_set_docs(). variety of di erent ways. One of the
A list of status, easiest way to deploy Plumber APIs is using RStudio Connect,
res$toResponse() toResponse()
headers, and body which supports push button publishing from the RStudio IDE.
RStudio® is a trademark of RStudio, Inc. • CC BY SA RStudio • info@rstudio.com • 844-448-1212 • rstudio.com • Learn more at www.rplumber.io • plumber 1.1.0 • Updated: 2021-03

ff

ff

ft

You might also like