class: center, middle, inverse, title-slide # How to turn your existing R code into a RESTful API ## An introduction to the plumber package ### Ellis Valentiner ### November 10, 2016 --- class: center, middle # About me --- ## About me - Data Scientist at Powerley - R user since 2008 - Grew up outside Minneapolis, MN - BA in psychology from University of Minnesota Morris - MS in statistics from Carnegie Mellon University --- class: center, middle # Ideas Not everyone is a data scientist Code handoffs present opportunities for errors Models can be slow to train but quick to serve --- # Hypothetical You're working as a Data Scientist for Big Health System and you're asked to build a model to identify whether ER patients are likely to experience a "negative outcome". Using electronic medical records and machine learning, you build a *great* model. How will the clinicians use your model? -- - Handoff your model to "a real programmer"? -- - Create an Excel spreadsheet template for the clinicians? -- - Build a Shiny app for the clinicians? -- - Construct a RESTful API and integrate it with their existing software? --- class: center, middle # Why use a RESTful API? -- Simple but powerful architecture -- Familiar to software developers and engineers -- No need to hand off your code -- Not restricted to the R ecosystem --- class: center, middle # What is a REST API? -- **Re**presentational **S**tate **T**ransfer -- Architecture not a protocol -- Four verbs: `GET`, `POST`, `PUT`, `DELETE` -- Uniform Resource Identifiers: `protocol://host:port/version/service/...` --- class: center, middle, inverse ![](http://plumber.trestletech.com/components/images/plumber.png) # Meet Plumber ??? Image credit: [plumber](https://www.rplumber.io) --- # Plumber -- Add decorators to your existing functions (e.g. "`#* @get`") -- Supports authentication -- Supports static, variable, and typed variable routes -- Built on `httpuv` (R), `libuv` (C), and `http-parser` (C) -- [http://plumber.trestletech.com](http://plumber.trestletech.com) --- # Decorators and Endpoints - Decorators are special comment lines - Use either `#*` or `#'` prefixes (`#*` is recommended) - Create endpoints using `@get`, `@post`, `@put`, and `@delete` - Endpoints may by accessed via multiple methods - Each request is served by the first endpoint it matches ```r #* @get /hello function(){ return("hello world") } ``` --- # Routes - Literal routes with fully specified path - Variable routes for more flexible routing ```r # Static route #* @get /user/me function(){...} # Variable route #* @get /user/<id> function(id){...} # Typed variable routes #* @get /user/<id:int> function(id){...} ``` --- # Filters `@filter` allows you to use and modify the request (`req`) `@preempt` lets you position a route in front of a specified filter ```r #* @filter logger function(req){ print(paste0(date(), " - ", req$REMOTE_ADDR, " - ", req$REQUEST_METHOD, " ", req$PATH_INFO)) forward() } #* @preempt logger #* @get / function(){} ``` --- class: center, middle, inverse # Example 1 --- # `myfile.R` ```r #* @filter logger function(req){ print(paste0(date(), " - ", req$REMOTE_ADDR, " - ", req$REQUEST_METHOD, " ", req$PATH_INFO)) forward() } #* @get /mean normalMean <- function(samples=10){ mean(rnorm(samples)) } #* @post /sum addTwo <- function(a, b){ as.numeric(a) + as.numeric(b) } ``` --- ## Running ```r # Install the package install.packages("plumber") # Load the package library(plumber) # plumb your file r <- plumb("myfile.R") # Start the router r$run() ``` --- class: center, middle, inverse # Example 2 --- # `iris.R` ```r #* @post /iris function(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width){ model <- randomForest::randomForest(Species ~ ., iris) newData <- data.frame(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) predict(model, newdata = newData) } ``` --- class: center, middle, inverse # Extras --- ## Extras Programmatic usage Static assert server --- class: center, middle, inverse # Alternatives --- ## CRAN Task View: Web Technologies and Services - DeployR - Shiny - fiery - prarie - rcloud - Rook - RServe - httpuv - jug - FastRWeb --- ## DeployR <img src="https://docs.microsoft.com/en-us/r-server/deployr/media/deployr-about/deployrworkflowstory.png" style="max-height: 80%; display: block; margin: 0 auto;"> ??? Image credit: [Microsoft](https://docs.microsoft.com/en-us/r-server/deployr/deployr-about) --- class: center, middle # Summary RESTful APIs are great plumber makes it easy to serve up your R code --- class: center, middle, inverse # Questions?