Введение в Plumber и REST
Изучите принципы REST и аннотируйте функции R как конечные точки API
«Введение в Plumber и REST» — бесплатный урок R Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.
Что такое REST API
REST (передача репрезентативного состояния) API — это веб-служба, которая предоставляет данные и операции через HTTP. Основные принципы:
- Без сохранения состояния: каждый запрос содержит всю необходимую информацию; сеанс на стороне сервера не сохраняется.
- Ориентация на ресурсы: конечные точки представляют ресурсы (
/users,/predictions). - Стандартные методы HTTP: GET (чтение), POST (создание), PUT (обновление), DELETE (удаление).
- JSON: стандартный формат данных для тел запросов и ответов.
# REST API concepts in HTTP terms:
# GET /api/model/predict?x=5 -> read a prediction
# POST /api/model/train -> create a new model
# GET /api/data/summary -> read data summary
# DELETE /api/cache/flush -> remove cached results
# Plumber maps R functions to these HTTP endpoints
cat('REST: stateless, resource-oriented, JSON responses')Синтаксис аннотаций plumber
plumber использует специальные аннотации в комментариях, начинающиеся с #*, чтобы определять конечные точки API. Размещайте аннотацию непосредственно над функцией R, которая обрабатывает конечную точку. Аргументы функции соответствуют параметрам запроса, а возвращаемое значение становится телом ответа JSON.
# plumber.R
library(plumber)
#* @get /ping
function() {
list(status = 'ok', time = Sys.time())
}
#* @get /add
#* @param a:int First number
#* @param b:int Second number
function(a, b) {
list(result = as.integer(a) + as.integer(b))
}pr() — создание маршрутизатора Plumber
pr('plumber.R') считывает файл plumber и создает объект маршрутизатора, регистрирующий все аннотированные конечные точки. Маршрутизатор — это центральный объект, который Вы настраиваете (добавляете фильтры, сериализаторы и т. д.) перед запуском.
library(plumber)
# Create a router from a plumber file
api <- pr('plumber.R')
# Inspect registered routes
print(api$routes)
# Alternatively, define inline without a file:
api <- pr() |>
pr_get('/ping', function() list(status = 'ok')) |>
pr_post('/echo', function(req) req$body)pr_run() — запуск сервера
pr_run(router, host, port) запускает сервер API plumber. По умолчанию он привязывается к 127.0.0.1:8000. Установите host = '0.0.0.0', чтобы принимать соединения через любой сетевой интерфейс (это требуется для Docker или удаленного доступа).
library(plumber)
api <- pr('plumber.R')
# Start server on localhost port 8000
# pr_run(api, host = '127.0.0.1', port = 8000)
# For Docker/remote access, bind to all interfaces
# pr_run(api, host = '0.0.0.0', port = 8000)
# View auto-generated Swagger docs in browser
# (automatically available at /docs or /__docs__/ endpoint)
cat('Swagger UI auto-generated at http://localhost:8000/__docs__/')Аннотация @get
Аннотация #* @get /path связывает запрос GET с функцией. Параметры строки запроса (например, ?name=Alice) автоматически передаются как аргументы функции R. Если аннотация преобразования не указана, параметры передаются как строки.
# plumber.R
#* Greet a user by name
#* @param name:str The name to greet
#* @get /greet
function(name = 'World') {
list(
message = paste('Hello,', name),
timestamp = format(Sys.time(), '%Y-%m-%d %H:%M:%S')
)
}
# GET /greet?name=Alice
# -> {"message":"Hello, Alice","timestamp":"2026-01-01 12:00:00"}Аннотация @post
Аннотация #* @post /path связывает запрос POST с функцией. Тело запроса (обычно JSON) доступно через специальный аргумент req как req$body (распарсированный список, если тело запроса содержит JSON). POST используется для операций, которые создают ресурсы или запускают вычисления.
# plumber.R
#* Run a linear model prediction
#* @post /predict
function(req) {
# req$body is already parsed from JSON
input_data <- as.data.frame(req$body)
# Run prediction with a pre-loaded model
predictions <- predict(trained_model, newdata = input_data)
list(
predictions = as.numeric(predictions),
n = nrow(input_data)
)
}Сериализатор JSON
По умолчанию plumber сериализует возвращаемые значения в JSON с помощью jsonlite. Аннотация #* @serializer json явно задает это поведение. Параметры сериализатора, например форматирование или обработку значений null, можно настроить, указав их в аннотации в виде списка JSON.
# Default: automatic JSON serialization
#* @get /data
function() {
list(values = 1:5, labels = c('a', 'b', 'c', 'd', 'e'))
}
# Explicit JSON serializer with options
#* @serializer json list(na = 'null', auto_unbox = TRUE)
#* @get /data_explicit
function() {
list(value = 42, missing = NA)
}
# With auto_unbox=TRUE: {"value":42} not {"value":[42]}Методы HTTP — PUT, DELETE, PATCH
plumber поддерживает все стандартные методы HTTP с помощью соответствующих аннотаций:
#* @put /path: полная замена ресурса.#* @delete /path: удаление ресурса.#* @patch /path: частичное обновление ресурса.#* @head /path: только заголовки, без тела.
# plumber.R — CRUD-style endpoints
#* Update a model configuration
#* @put /config/<model_id>
function(model_id, req) {
config <- req$body
save_config(model_id, config)
list(updated = model_id, config = config)
}
#* Remove cached results
#* @delete /cache/<key>
function(key) {
cache_env <- globalenv()$cache
rm(list = key, envir = cache_env)
list(deleted = key)
}Параметры пути
Параметры пути задаются с помощью угловых скобок в маршруте: /user/. plumber извлекает значение из URL и передает его функции как аргумент с тем же именем. Они отличаются от параметров запроса, которые указываются после ?.
# plumber.R
#* Get stats for a specific dataset
#* @param dataset_id:str The dataset identifier
#* @get /datasets/<dataset_id>/stats
function(dataset_id) {
if (!dataset_id %in% available_datasets()) {
stop(paste('Dataset not found:', dataset_id))
}
ds <- load_dataset(dataset_id)
list(
id = dataset_id,
rows = nrow(ds),
cols = ncol(ds),
names = names(ds)
)
}Обработка ошибок
Когда функция R вызывает ошибку, plumber перехватывает ее и возвращает ответ HTTP 500 с сообщением об ошибке в формате JSON. В API, предназначенных для пользователей, явно возвращайте подходящие коды состояния HTTP с помощью res$status, а для ошибок проверки используйте stop().
# plumber.R
#* Divide two numbers safely
#* @get /divide
function(a, b, res) {
a <- suppressWarnings(as.numeric(a))
b <- suppressWarnings(as.numeric(b))
if (is.na(a) || is.na(b)) {
res$status <- 400 # Bad Request
return(list(error = 'Both a and b must be numeric'))
}
if (b == 0) {
res$status <- 422 # Unprocessable Entity
return(list(error = 'Division by zero is not allowed'))
}
list(result = a / b)
}Автоматически создаваемая документация Swagger
plumber автоматически создает интерактивную документацию Swagger UI на основе Ваших аннотаций. Откройте /__docs__/, когда сервер запущен, чтобы увидеть все конечные точки и их параметры, а также опробовать их в браузере. Используйте #* @tag, чтобы логически сгруппировать конечные точки.
# plumber.R with Swagger metadata
#* @apiTitle My ML Prediction API
#* @apiDescription Serves predictions from trained R models
#* @apiVersion 1.0.0
#* @tag model
#* @get /health
function() list(status = 'healthy')
#* Predict house price
#* @tag prediction
#* @param sqft:dbl Square footage
#* @param bedrooms:int Number of bedrooms
#* @get /predict
function(sqft = 1000, bedrooms = 3) {
pred <- predict(price_model, data.frame(sqft = as.numeric(sqft),
bedrooms = as.integer(bedrooms)))
list(predicted_price = round(as.numeric(pred), 2))
}Быстрая проверка
В plumber, чем отличается параметр запроса (например, /greet?name=Alice) от параметра пути (например, /user/42)?
Итоги по plumber и REST
Основные выводы из урока «Введение в plumber и REST»:
- REST: не сохраняет состояние, ориентирован на ресурсы, использует стандартные методы HTTP и возвращает JSON.
- plumber связывает функции R с конечными точками с помощью аннотаций
#*над функциями. pr('file.R')создает маршрутизатор;pr_run(api, host, port)запускает сервер.#* @get /pathобрабатывает GET;#* @post /pathобрабатывает POST.- Параметры пути:
/user/; параметры запроса:/search?term=foo. - Возвращайте именованные списки — plumber автоматически сериализует их в JSON.
- Swagger UI автоматически создается по адресу
/__docs__/на основе Ваших аннотаций.
# Complete minimal plumber API
library(plumber)
#* @apiTitle Simple Prediction API
#* Health check
#* @get /health
function() list(status = 'ok')
#* Predict mpg from weight
#* @param wt:dbl Car weight (1000 lbs)
#* @get /predict
function(wt = 3.0) {
pred <- predict(lm(mpg ~ wt, data = mtcars),
newdata = data.frame(wt = as.numeric(wt)))
list(wt = as.numeric(wt), predicted_mpg = round(pred, 2))
}
# Run:
# api <- pr('plumber.R')
# pr_run(api, port = 8000)Изучай R с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 43
- Уроки
- 159
Часто задаваемые вопросы
Урок «Введение в Plumber и REST» бесплатный?
Да — полный текст урока «Введение в Plumber и REST» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.
Чему я научусь в уроке «Введение в Plumber и REST»?
Изучите принципы REST и аннотируйте функции R как конечные точки API Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать R Academy?
Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Введение в Plumber и REST»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке R Academy?
Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Введение в Plumber и REST
- Создание конечных точек GET и POST
- Аутентификация и безопасность API
- Развёртывание API Plumber в рабочей среде