0Pricing
R Academy · Leçon

Introduction à Plumber et REST

Comprenez les principes REST et annotez des fonctions R comme points d’accès d’API.

Introduction à Plumber et REST est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.

Qu’est-ce qu’une API REST ?

Une API REST (Representational State Transfer) est un service web qui expose des données et des opérations via HTTP. Principes clés :

  • Sans état : chaque requête contient toutes les informations nécessaires ; aucune session côté serveur.
  • Orientée ressources : les points de terminaison représentent des ressources (/users, /predictions).
  • Verbes HTTP standard : GET (lire), POST (créer), PUT (mettre à jour), DELETE (supprimer).
  • JSON : the format de données standard pour les corps des requêtes et des réponses.
# 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')

Syntaxe des annotations de plumber

plumber utilise des annotations spéciales sous forme de commentaires, commençant par #*, pour définir des points de terminaison d’API. Placez une annotation directement au-dessus de la fonction R qui gère le point de terminaison. Les arguments de la fonction correspondent aux paramètres de la requête ; la valeur renvoyée devient le corps de la réponse 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() — Créer un routeur Plumber

pr('plumber.R') lit un fichier plumber et crée un objet routeur qui enregistre tous les points de terminaison annotés. Le routeur est l’objet central que vous configurez (ajout de filtres, de sérialiseurs, etc.) avant de le démarrer.

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() — Démarrer le serveur

pr_run(router, host, port) démarre le serveur d’API plumber. Par défaut, il se lie à 127.0.0.1:8000. Définissez host = '0.0.0.0' pour accepter les connexions depuis toute interface réseau (ce qui est nécessaire avec Docker ou pour un accès distant).

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

Annotation @get

L’annotation #* @get /path associe une requête GET à la fonction. Les paramètres de chaîne de requête (par exemple ?name=Alice) sont automatiquement transmis comme arguments de la fonction R. Si aucune annotation de conversion n’est fournie, les paramètres sont reçus sous forme de chaînes de caractères.

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

Annotation @post

L’annotation #* @post /path associe une requête POST à la fonction. Le corps de la requête (généralement au format JSON) est accessible via l’argument spécial req, sous la forme req$body (une liste analysée lorsque le corps de la requête est au format JSON). POST est utilisé pour les opérations qui créent des ressources ou déclenchent des calculs.

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

Sérialiseur JSON

Par défaut, plumber sérialise les valeurs renvoyées au format JSON à l’aide de jsonlite. L’annotation #* @serializer json rend ce comportement explicite. Vous pouvez configurer des options de sérialisation, comme l’impression avec indentation ou la gestion des valeurs nulles, en les indiquant sous forme de liste JSON dans l’annotation.

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

Verbes HTTP — PUT, DELETE, PATCH

plumber prend en charge tous les verbes HTTP standard au moyen d’annotations correspondantes :

  • #* @put /path : remplacement complet d’une ressource.
  • #* @delete /path : suppression d’une ressource.
  • #* @patch /path : mise à jour partielle d’une ressource.
  • #* @head /path : en-têtes uniquement, sans corps.
# 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)
}

Paramètres de chemin

Les paramètres de chemin sont définis entre chevrons dans la route : /user/. plumber extrait la valeur de l’URL et la transmet comme argument de fonction portant le même nom. Ils se distinguent des paramètres de requête, qui apparaissent après ?.

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

Gestion des erreurs

Lorsqu’une fonction R déclenche une erreur, plumber l’intercepte et renvoie une réponse HTTP 500 contenant le message d’erreur au format JSON. Pour les API destinées aux utilisateurs, renvoyez explicitement les codes d’état HTTP appropriés à l’aide de res$status et de stop() pour les erreurs de validation.

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

Documentation Swagger générée automatiquement

plumber génère automatiquement une documentation interactive Swagger UI à partir de vos annotations. Consultez /__docs__/ lorsque le serveur est en cours d’exécution pour voir tous les points de terminaison et leurs paramètres, et pour les essayer dans le navigateur. Utilisez #* @tag pour regrouper logiquement les points de terminaison.

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

Vérification rapide

Dans plumber, quelle est la différence entre un paramètre de requête (par exemple /greet?name=Alice) et un paramètre de chemin (par exemple /user/42) ?

Récapitulatif de plumber et REST

Points clés de l’introduction à plumber et REST :

  • REST : sans état, orienté ressources, utilise les verbes HTTP standard et renvoie du JSON.
  • plumber associe des fonctions R à des points de terminaison au moyen d’annotations #* placées au-dessus des fonctions.
  • pr('file.R') crée un routeur ; pr_run(api, host, port) démarre le serveur.
  • #* @get /path gère GET ; #* @post /path gère POST.
  • Paramètres de chemin : /user/ ; paramètres de requête : /search?term=foo.
  • Renvoyez des listes nommées : plumber les sérialise automatiquement au format JSON.
  • Swagger UI est générée automatiquement à l’adresse /__docs__/ à partir de vos annotations.
# 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)

Questions Fréquemment Posées

La leçon « Introduction à Plumber et REST » est-elle gratuite ?

Oui — le texte complet de « Introduction à Plumber et REST » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Introduction à Plumber et REST » ?

Comprenez les principes REST et annotez des fonctions R comme points d’accès d’API. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer R Academy ?

Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Introduction à Plumber et REST » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon R Academy ?

Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Introduction à Plumber et REST
  2. Créer des points d’accès GET et POST
  3. Authentification et sécurité des API
  4. Déployer des API Plumber en production
← Retour à R Academy