0Pricing
R Academy · บทเรียน

แนะนำ Plumber และ REST

ทำความเข้าใจหลักการ REST และใส่คำอธิบายประกอบให้ฟังก์ชัน R เป็นจุดปลายทาง API

แนะนำ Plumber และ REST เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

REST API คืออะไร

REST (Representational State Transfer) 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)

คำถามที่พบบ่อย

บทเรียน “แนะนำ Plumber และ REST” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “แนะนำ Plumber และ REST” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “แนะนำ Plumber และ REST”

ทำความเข้าใจหลักการ REST และใส่คำอธิบายประกอบให้ฟังก์ชัน R เป็นจุดปลายทาง API คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 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. การนำ Plumber API ไปใช้งานจริง
← กลับไปที่ R Academy