0Pricing
R Academy · Lekcja

Wprowadzenie do Plumber i REST

Poznaj zasady REST i oznaczaj funkcje R jako endpointy API.

Wprowadzenie do Plumber i REST to bezpłatna lekcja R Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej R Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs R Academy zawiera 4 lekcji w sumie.

Czym jest REST API?

REST (Representational State Transfer) API to usługa internetowa udostępniająca dane i operacje za pośrednictwem protokołu HTTP. Najważniejsze zasady:

  • Bezstanowość: każde żądanie zawiera wszystkie potrzebne informacje; po stronie serwera nie ma sesji.
  • Orientacja na zasoby: endpointy reprezentują zasoby (/users, /predictions).
  • Standardowe metody HTTP: GET (odczyt), POST (tworzenie), PUT (aktualizacja), DELETE (usuwanie).
  • JSON: standardowy format danych w treści żądań i odpowiedzi.
# 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')

Składnia adnotacji plumber

plumber używa specjalnych adnotacji w komentarzach, zaczynających się od #*, do definiowania endpointów API. Adnotację należy umieścić bezpośrednio nad funkcją R obsługującą endpoint. Argumenty funkcji są mapowane na parametry żądania, a wartość zwracana staje się treścią odpowiedzi w formacie 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() — tworzenie routera Plumber

pr('plumber.R') odczytuje plik plumber i tworzy obiekt routera, który rejestruje wszystkie endpointy opatrzone adnotacjami. Router jest centralnym obiektem konfigurowanym przed uruchomieniem, na przykład przez dodanie filtrów i serializatorów.

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() — uruchamianie serwera

pr_run(router, host, port) uruchamia serwer API plumber. Domyślnie nasłuchuje on na adresie 127.0.0.1:8000. Ustawienie host = '0.0.0.0' pozwala akceptować połączenia z dowolnego interfejsu sieciowego i jest wymagane w przypadku Dockera lub dostępu zdalnego.

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

Adnotacja @get

Adnotacja #* @get /path mapuje żądanie GET na funkcję. Parametry zapytania (np. ?name=Alice) są automatycznie przekazywane jako argumenty funkcji R. Jeśli nie podano adnotacji konwersji, parametry są przekazywane jako ciągi znaków.

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

Adnotacja @post

Adnotacja #* @post /path mapuje żądanie POST na funkcję. Treść żądania, zazwyczaj w formacie JSON, jest dostępna za pośrednictwem specjalnego argumentu req jako req$body — w przypadku żądania JSON jest to sparsowana lista. Metody POST używa się do operacji tworzących zasoby lub uruchamiających obliczenia.

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

Serializator JSON

Domyślnie plumber serializuje wartości zwracane przez funkcje do formatu JSON za pomocą jsonlite. Adnotacja #* @serializer json jawnie określa to zachowanie. Opcje serializatora, takie jak formatowanie czy obsługa wartości null, można skonfigurować, podając je jako listę JSON w adnotacji.

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

Metody HTTP — PUT, DELETE, PATCH

plumber obsługuje wszystkie standardowe metody HTTP za pomocą odpowiadających im adnotacji:

  • #* @put /path: pełne zastąpienie zasobu.
  • #* @delete /path: usunięcie zasobu.
  • #* @patch /path: częściowa aktualizacja zasobu.
  • #* @head /path: tylko nagłówki, bez treści.
# 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)
}

Parametry ścieżki

Parametry ścieżki definiuje się za pomocą nawiasów ostrych w trasie: /user/. plumber wyodrębnia wartość z adresu URL i przekazuje ją do funkcji jako argument o tej samej nazwie. Różnią się one od parametrów zapytania, które występują za znakiem ?.

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

Obsługa błędów

Gdy funkcja R zgłosi błąd, plumber przechwytuje go i zwraca odpowiedź HTTP 500 z komunikatem błędu w formacie JSON. W interfejsach API przeznaczonych dla użytkowników należy jawnie zwracać odpowiednie kody stanu HTTP za pomocą res$status oraz stop() w przypadku błędów walidacji.

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

Automatycznie generowana dokumentacja Swagger

plumber automatycznie generuje interaktywną dokumentację Swagger UI na podstawie adnotacji. Gdy serwer działa, należy przejść do /__docs__/, aby zobaczyć wszystkie endpointy i ich parametry oraz przetestować je w przeglądarce. Za pomocą #* @tag można logicznie grupować endpointy.

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

Szybkie sprawdzenie

W plumber jaka jest różnica między parametrem zapytania (np. /greet?name=Alice) a parametrem ścieżki (np. /user/42)?

Podsumowanie plumber i REST

Najważniejsze informacje z lekcji Wprowadzenie do plumber i REST:

  • REST: jest bezstanowy, zorientowany na zasoby, używa standardowych metod HTTP i zwraca dane w formacie JSON.
  • plumber mapuje funkcje R na endpointy za pomocą adnotacji #* umieszczanych nad funkcjami.
  • pr('file.R') tworzy router, a pr_run(api, host, port) uruchamia serwer.
  • #* @get /path obsługuje GET, a #* @post /path obsługuje POST.
  • Parametry ścieżki: /user/; parametry zapytania: /search?term=foo.
  • Należy zwracać nazwane listy — plumber automatycznie serializuje je do formatu JSON.
  • Swagger UI jest automatycznie generowany pod adresem /__docs__/ na podstawie adnotacji.
# 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)

Często zadawane pytania

Czy lekcja „Wprowadzenie do Plumber i REST” jest bezpłatna?

Tak — pełny tekst „Wprowadzenie do Plumber i REST” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu R Academy, przejdź na CoddyKit PRO. Kurs R Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wprowadzenie do Plumber i REST”?

Poznaj zasady REST i oznaczaj funkcje R jako endpointy API. Ćwiczysz R Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć R Academy?

Nie wymagamy żadnego doświadczenia. R Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Wprowadzenie do Plumber i REST”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji R Academy?

Tak. Każda lekcja R Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wprowadzenie do Plumber i REST
  2. Tworzenie endpointów GET i POST
  3. Uwierzytelnianie i bezpieczeństwo API
  4. Wdrażanie API Plumber na produkcji
← Powrót do R Academy