R Academy · Урок

Введение в Plumber и REST

Изучите принципы REST и аннотируйте функции R как конечные точки API

Урок 1 из 413 шагов

«Введение в 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 — локальная установка не требуется.

Все уроки этого курса

  1. Введение в Plumber и REST
  2. Создание конечных точек GET и POST
  3. Аутентификация и безопасность API
  4. Развёртывание API Plumber в рабочей среде
← Назад к R Academy