0Pricing
R Academy · Lección

Introducción a Plumber y REST

Comprenda los principios de REST y anote funciones de R como endpoints de API.

Introducción a Plumber y REST es una lección gratuita de R Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de R Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de R Academy incluye 4 lecciones en total.

¿Qué es una API REST?

Una API REST (Representational State Transfer) es un servicio web que expone datos y operaciones mediante HTTP. Principios clave:

  • Sin estado: cada solicitud contiene toda la información necesaria; no hay una sesión en el servidor.
  • Orientada a recursos: los endpoints representan recursos (/users, /predictions).
  • Verbos HTTP estándar: GET (leer), POST (crear), PUT (actualizar), DELETE (eliminar).
  • JSON: el formato de datos estándar para los cuerpos de las solicitudes y las respuestas.
# 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')

Sintaxis de anotaciones de plumber

plumber utiliza anotaciones especiales en comentarios que comienzan con #* para definir endpoints de API. Coloque una anotación justo encima de la función de R que gestiona el endpoint. Los argumentos de la función se asignan a los parámetros de la solicitud; el valor devuelto se convierte en el cuerpo de la respuesta 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() — Creación de un router de Plumber

pr('plumber.R') lee un archivo de plumber y crea un objeto router que registra todos los endpoints anotados. El router es el objeto central que se configura (para añadir filtros, serializadores, etc.) antes de ejecutarlo.

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() — Inicio del servidor

pr_run(router, host, port) inicia el servidor de la API de plumber. De forma predeterminada, se enlaza a 127.0.0.1:8000. Establezca host = '0.0.0.0' para aceptar conexiones desde cualquier interfaz de red (necesario para Docker o el acceso remoto).

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__/')

Anotación @get

La anotación #* @get /path asigna una solicitud GET a la función. Los parámetros de la cadena de consulta (por ejemplo, ?name=Alice) se pasan automáticamente como argumentos de la función de R. Si no se proporciona ninguna anotación de conversión, los parámetros llegan como cadenas de caracteres.

# 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"}

Anotación @post

La anotación #* @post /path asigna una solicitud POST a la función. El cuerpo de la solicitud (normalmente en formato JSON) está disponible mediante el argumento especial req como req$body (una lista analizada cuando el cuerpo de la solicitud es JSON). POST se utiliza para operaciones que crean recursos o desencadenan cálculos.

# 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)
  )
}

Serializador JSON

De forma predeterminada, plumber serializa los valores devueltos a JSON mediante jsonlite. La anotación #* @serializer json lo hace explícito. Puede configurar opciones del serializador, como el formato legible o la gestión de valores nulos, especificándolas como una lista JSON en la anotación.

# 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]}

Verbos HTTP — PUT, DELETE, PATCH

plumber admite todos los verbos HTTP estándar mediante las anotaciones correspondientes:

  • #* @put /path: reemplazo completo de un recurso.
  • #* @delete /path: elimina un recurso.
  • #* @patch /path: actualización parcial de un recurso.
  • #* @head /path: solo encabezados (sin cuerpo).
# 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)
}

Parámetros de ruta

Los parámetros de ruta se definen mediante corchetes angulares en la ruta: /user/. plumber extrae el valor de la URL y lo pasa como argumento de la función con el mismo nombre. Se diferencian de los parámetros de consulta, que aparecen después de ?.

# 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)
  )
}

Gestión de errores

Cuando una función de R produce un error, plumber lo captura y devuelve una respuesta HTTP 500 con el mensaje de error en formato JSON. En las API orientadas a usuarios, devuelva explícitamente los códigos de estado HTTP adecuados mediante res$status y stop() para los errores de validación.

# 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)
}

Documentación de Swagger generada automáticamente

plumber genera automáticamente documentación interactiva de Swagger UI a partir de las anotaciones. Visite /__docs__/ cuando el servidor esté en ejecución para ver todos los endpoints y sus parámetros, y probarlos en el navegador. Use #* @tag para agrupar los endpoints de forma lógica.

# 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))
}

Comprobación rápida

En plumber, ¿cuál es la diferencia entre un parámetro de consulta (por ejemplo, /greet?name=Alice) y un parámetro de ruta (por ejemplo, /user/42)?

Resumen de plumber y REST

Conclusiones clave de Introducción a plumber y REST:

  • REST: no tiene estado, está orientado a recursos, utiliza verbos HTTP estándar y devuelve JSON.
  • plumber asigna funciones de R a endpoints mediante anotaciones #* encima de las funciones.
  • pr('file.R') crea un router; pr_run(api, host, port) inicia el servidor.
  • #* @get /path gestiona GET; #* @post /path gestiona POST.
  • Parámetros de ruta: /user/; parámetros de consulta: /search?term=foo.
  • Devuelva listas con nombres; plumber las serializa automáticamente a JSON.
  • Swagger UI se genera automáticamente en /__docs__/ a partir de las anotaciones.
# 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)

Preguntas frecuentes

¿La lección «Introducción a Plumber y REST» es gratis?

Sí — el texto completo de «Introducción a Plumber y REST» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de R Academy, actualiza a CoddyKit PRO. El curso de R Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Introducción a Plumber y REST»?

Comprenda los principios de REST y anote funciones de R como endpoints de API. Practicas R Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar R Academy?

No se requiere experiencia previa. R Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Introducción a Plumber y REST»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de R Academy?

Sí. Cada lección de R Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Introducción a Plumber y REST
  2. Creación de endpoints GET y POST
  3. Autenticación y seguridad de API
  4. Implementación de API de Plumber en producción
← Volver a R Academy