0Pricing
R Academy · レッスン

Plumber と REST の基礎

REST の原則を理解し、R 関数にアノテーションを付けて API エンドポイントとして定義します。

「Plumber と REST の基礎」はCoddyKit上の無料R Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。

REST APIとは

REST(Representational State Transfer)APIは、HTTP経由でデータや操作を公開するWebサービスです。主な原則は次のとおりです。

  • ステートレス:各リクエストに必要な情報がすべて含まれ、サーバー側のセッションを保持しません。
  • リソース指向:エンドポイントがリソース(/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)はplumber APIサーバーを起動します。デフォルトでは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はjsonliteを使って戻り値をJSONにシリアライズします。#* @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はそれを捕捉し、エラーメッセージをJSONに含めたHTTP 500レスポンスを返します。ユーザー向けAPIでは、res$statusとstop()を使って検証エラーに適切なHTTPステータスコードを明示的に設定してください。

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

よくある質問

「Plumber と REST の基礎」レッスンは無料ですか?

はい。「Plumber と REST の基礎」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。

「Plumber と REST の基礎」で何を学びますか?

REST の原則を理解し、R 関数にアノテーションを付けて API エンドポイントとして定義します。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

R Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「Plumber と REST の基礎」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このR Academyレッスンでコードを書いて実行できますか?

はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Plumber と REST の基礎
  2. GET エンドポイントと POST エンドポイントの作成
  3. 認証と API セキュリティ
  4. Plumber API を本番環境にデプロイする
← R Academyに戻る