Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
REST APIs with R and Plumber
REST APIs are everywhere around us. Software engineers use them to develop backend logic, and data scientists use them to deploy machine learning models. Today you’ll learn how to make a basic REST API with R and the plumber
package.
Completely new to R? Check out our detailed R tutorial for programmers.
Jump to a section:
Introduction to REST APIs
REST stands for “Representational State Transfer”. In simpler words, it represents a set of rules that developers follow when creating APIs. The most common rule is that you should get a piece of data (response) whenever you make a request to a particular URL.
The request you make is made of four components:
- Endpoint – a part of the URL you visit. For example, the endpoint of the URL https://example.com/predict is /predict
- Method – a type of request you’re sending, can be either GET, POST, PUT, PATCH, and DELETE. They are used to perform one of these actions: Create, Read, Update, Delete (CRUD)
- Headers – used for providing information (think authentication credentials, for example). They are provided as key-value pairs
- Body – information that is sent to the server. Used only when not making GET requests.
Most of the time, the response returned after making a request is in JSON format. The alternative format is XML, but JSON is more common. You can also return other objects, such as images instead. You’ll learn how to do that today.
R allows you to develop REST APIs with the plumber
package. You can read the official documentation here.
It’s easy to repurpose any R script file to an API with plumber
, because you only have to decorate your functions with comments. You’ll see all about it in a bit.
Develop a Simple REST API with R and Plumber
To start, create an empty R script file. You’ll need a couple of packages:
plumber
– to develop the APIdplyr
– to filter datasets based on the request body (or URL params)ggplot2
– for data visualizationgapminder
– for data. That’s what you’ll use as a basis for the API.
You can place two roxigen2
-like comments for specifying API title and description. These two aren’t mandatory, but you shouldn’t skip them. Here’s how the entire code snippet (imports, name, and description) looks like:
You’re now ready to create your first endpoint.
Endpoint 1 – /countries
The idea behind this endpoint is that it should return countries and their respective data after a couple of filters are applied. To be more precise, this endpoint accepts parameter values for continent, life expectancy, and population. Value for continent must be exact, and values for the other two parameters filter data so that only rows with greater values are returned.
If you want to do things right, it’ll require many comments, as you’ve seen previously. It’s a good practice to write a short description, list the parameters, and it’s mandatory to specify the request type and the endpoint.
Below the comments, you’ll place a function that performs the necessary logic and returns the results.
Let’s think about the parameters for a second. You’ll need:
- continent – column continent
- life expectancy – column lifeExp
- population – column pop
All three are mandatory, and you can do the filtering based on the parameter values with the dplyr
package. This endpoint will return data for the most recent year only, which is 2007.
Here’s the complete logic behind /countries endpoint:
If you were to run the API now, this is what you’d see:
The endpoint on the bottom of the image (blue box) is clickable. Clicking on it expands a whole another section:
You can click on the “Try it out” button to make a request straight from the browser. You’ll have to fill in the parameter values then; let’s say like this:
Once you click on the “Execute” button, the response will show below. Here’s how it looks like in this case:
And that’s your first endpoint! It takes data in and returns data out. But what if you want to return something else? Like an image, for example. You’ll learn how to do that next.
Endpoint 2 – /plot
This endpoint will be quite different. The goal now is to return an image instead of raw data. The image will contain a line plot made with ggplot2
, showing life expectancy over time.
Two parameters are required – country and chart title – both are self-explanatory.
If you want to return an image from an API with R, you’ll have to put the following comment: #* @serializer contentType list(type='image/png')
. Everything else is more or less the same.
Regarding the visualization, a subset is made from the original dataset containing only records for the specified country. A simple line and marker plot is then made from the dataset.
The problem is – you can’t return a ggplot2
visualization. You’ll have to save the image with the ggsave()
function and then return it with the readBin()
function.
Here’s the entire snippet:
If you were to run the API now, a new endpoint would immediately catch your attention:
Here’s how its documentation looks like:
You can once again click on the “Try it out” button to test the functionality. Let’s see how life expectancy changed over time in Poland:
Once you click on the “Execute” button, you’ll be presented with the following visualization:
And that’s how you can return an image in the API response. You’ve only created endpoints with the GET method so far. You’ll learn how to work with POST next.
Endpoint 3 – /calculate_gdp
You’ll now learn how to work with POST methods (or any other sends data in the request body). The goal is to create another endpoint that calculates the total GDP for a specified country in the latest year (2007).
The only parameter you’ll need is the country.
Once you have this value, you can use dplyr
and the summarize()
function to calculate the total GDP. Here’s the entire code snippet:
If you were to run the API now, you would instantly see a new box, which is green this time, indicating the POST method:
You can once again click on the “Try it out” button to test the functionality:
Let’s see what was the total GDP of Poland in 2007:
Once you click on the “Execute” button, you’ll be presented with the following response:
The only difference here between GET and POST is that you can’t put parameters and their values in the URL for the POST. The parameters and values are passed in the request body as JSON.
You now know how to wrap your R code into a simple REST API. Let’s wrap things up next.
Conclusion
You’ve learned a lot today – what REST APIs are, what’s the deal with the plumber
package, and how to use it to build basic APIs in R programming language.
APIs in R are commonly developed for exposing the predictive functionality of machine learning models. You can do other things, of course (as demonstrated today), but R probably isn’t the best language for doing so. You’re probably better of with Java, Go, or JavaScript if that’s the case.
Learn More
- What Can I Do With R? 6 Essential R Packages for Programmers
- How to Analyze Data with R: A Complete Beginner Guide to dplyr
- Machine Learning with R: A Complete Guide to Linear Regression
- Machine Learning with R: A Complete Guide to Logistic Regression
Appsilon is hiring for remote roles! See our Careers page for all open positions, including R Shiny Developers, Fullstack Engineers, Frontend Engineers, a Senior Infrastructure Engineer, and a Community Manager. Join Appsilon and work on groundbreaking projects with the world’s most influential Fortune 500 companies.
Article How to Make REST APIs with R: A Beginners Guide to Plumber comes from Appsilon | End to End Data Science Solutions.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.