Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

อธิบายแร็คสำหรับนักพัฒนา Ruby

เกิดอะไรขึ้นเบื้องหลังของทุก Rails, Sinatra และเฟรมเวิร์กเว็บ Ruby อื่นๆ

คำตอบคือ Rack ซึ่งเป็นองค์ประกอบหลักที่ทำให้สิ่งนี้เป็นไปได้

แต่แร็คคืออะไรกันแน่?

Rack เป็นเลเยอร์ระหว่างเฟรมเวิร์ก (Rails) และแอพพลิเคชั่นเซิร์ฟเวอร์ (Puma)

อธิบายแร็คสำหรับนักพัฒนา Ruby

เป็นกาวที่ช่วยให้สื่อสารได้

เหตุใดเราจึงต้องใช้แร็ค

เราใช้แร็คเพราะทำให้เฟรมเวิร์กและเซิร์ฟเวอร์ต่างๆ สามารถใช้แทนกันได้

สิ่งเหล่านี้กลายเป็นส่วนประกอบที่คุณสามารถเสียบเข้าไปได้ .

ซึ่งหมายความว่าคุณสามารถใช้ Puma กับ Rails, Sinatra และเฟรมเวิร์กอื่นๆ ที่เข้ากันได้กับแร็ค ไม่ว่าคุณจะใช้เฟรมเวิร์กหรือเซิร์ฟเวอร์ใด หากพวกเขาใช้อินเทอร์เฟซของแร็ค .

ด้วย Rack ทุกองค์ประกอบทำงานและทุกคนก็มีความสุข!

Rack Middleware คืออะไร

แร็คตั้งอยู่ตรงกลางของทุกคำขอและการตอบสนองของเว็บ

ด้วยเหตุนี้ จึงสามารถทำหน้าที่เป็นผู้ปกครอง โดยการปฏิเสธการเข้าถึงคำขอที่ไม่ต้องการ หรือสามารถทำหน้าที่เป็นนักประวัติศาสตร์โดยการติดตามการตอบสนองที่ช้า

นั่นคือสิ่งที่แร็คมิดเดิลแวร์ คือ!

โปรแกรม Ruby ขนาดเล็กที่ถูกเรียกใช้โดยเป็นส่วนหนึ่งของวงจรการตอบกลับคำขอและมีโอกาสทำบางสิ่งกับมัน

สิ่งนี้ใช้สำหรับอะไร

  • การบันทึก
  • เซสชัน
  • การทำโปรไฟล์ (ค้นหาว่าคำขอใช้เวลานานเท่าใดจึงจะเสร็จสมบูรณ์)
  • แคช
  • ความปลอดภัย (ปฏิเสธคำขอตามที่อยู่ IP หรือจำกัด # คำขอ)
  • แสดงไฟล์สแตติก (css, js, png…)

สิ่งเหล่านี้มีประโยชน์มาก &Rails ใช้ประโยชน์จากมิดเดิลแวร์เพื่อนำฟังก์ชันบางอย่างไปใช้งาน .

คุณสามารถดูรายการมิดเดิลแวร์ด้วย rake middleware ภายในโครงการ Rails

ตอนนี้ อินเทอร์เฟซของชั้นวาง ฉันได้กล่าวไว้ก่อนหน้านี้

ลักษณะเป็นอย่างไร?

ผมขอแสดงให้คุณเห็นตัวอย่าง…

วิธีการเขียนแอปพลิเคชันแร็คของคุณเอง

คุณสามารถเรียนรู้วิธีการทำงานของ Rack โดยการเขียนใบสมัครของคุณเอง

มาทำสิ่งนี้กันเถอะ!

แอปพลิเคชัน Rack เป็นคลาสที่มีวิธีเดียว:call .

หน้าตาเป็นแบบนี้ :

require 'rack'

handler = Rack::Handler::Thin

class RackApp
  def call(env)
    [200, {"Content-Type" => "text/plain"}, "Hello from Rack"]
  end
end

handler.run RackApp.new

รหัสนี้จะเริ่มต้นเซิร์ฟเวอร์บนพอร์ต 8080 (ลองเลย! )

อาร์เรย์นี้ถูกส่งคืนอะไร

  • รหัสสถานะ HTTP (200)
  • ส่วนหัว HTTP (“ประเภทเนื้อหา”)
  • เนื้อหา (“สวัสดีจากแร็ค”)

หากคุณต้องการเข้าถึงรายละเอียดคำขอ คุณสามารถใช้ env อาร์กิวเมนต์

ถูกใจสิ่งนี้ :

req = Rack::Request.new(env)

วิธีการเหล่านี้ใช้ได้ :

  • path_info (/articles/1)
  • ip (ของผู้ใช้)
  • user_agent (Chrome, Firefox, Safari…)
  • request_method (รับ / โพสต์)
  • เนื้อหา (เนื้อหา)
  • media_type (ธรรมดา, json, html)

คุณสามารถใช้ข้อมูลนี้เพื่อ สร้างแอปพลิเคชัน Rack ของคุณ .

ตัวอย่างเช่น เราสามารถปฏิเสธการเข้าถึงเนื้อหาของเราได้หากที่อยู่ IP คือ 5.5.5.5 .

นี่คือรหัส :

require 'rack'

handler = Rack::Handler::Thin

class RackApp
  def call(env)
    req = Rack::Request.new(env)

    if req.ip == "5.5.5.5"
      [403, {}, ""]
    else
      [200, {"Content-Type" => "text/plain"}, "Hello from Rack"]
    end
  end
end

handler.run RackApp.new

คุณสามารถเปลี่ยนที่อยู่เป็น 127.0.0.1 ถ้าต้องการเห็นผล

หากไม่ได้ผล ให้ลอง ::1 , localhost เวอร์ชัน IPv6

วิธีการเขียนและใช้แร็คมิดเดิลแวร์

ตอนนี้:

คุณเชื่อมโยงแอปพลิเคชันและมิดเดิลแวร์เพื่อให้ทำงานร่วมกันได้อย่างไร

การใช้ Rack::Builder .

วิธีทำความเข้าใจที่ดีที่สุดคือการยกตัวอย่าง

นี่คือแอป Rack ของเรา :

require 'rack'

handler = Rack::Handler::Thin

class RackApp
  def call(env)
    req = Rack::Request.new(env)

    [200, {"Content-Type" => "text/plain"}, "Hello from Rack - #{req.ip}"]
  end
end

นี่คือมิดเดิลแวร์ :

class FilterLocalHost
  def initialize(app)
    @app = app
  end

  def call(env)
    req = Rack::Request.new(env)

    if req.ip == "127.0.0.1" || req.ip == "::1"
      [403, {}, ""]
    else
      @app.call(env)
    end
  end
end

นี่คือวิธีที่เรารวมมันเข้าด้วยกัน :

app =
Rack::Builder.new do |builder|
  builder.use FilterLocalHost
  builder.run RackApp.new
end

handler.run app

ในตัวอย่างนี้ เรามีแอปพลิเคชันแร็คสองตัว:

  • หนึ่งรายการสำหรับการตรวจสอบ IP (FilterLocalHost )
  • หนึ่งสำหรับแอปพลิเคชันเพื่อส่งเนื้อหา (HTML, JSON ฯลฯ)

ขอให้สังเกตว่า @app.call(env) นั่นคือสิ่งที่ทำให้ FilterLocalHost มิดเดิลแวร์

สองสิ่งนี้เกิดขึ้นได้ :

  • เราตอบกลับซึ่งจะหยุดห่วงโซ่มิดเดิลแวร์
  • เราส่งคำขอพร้อมกับ @app.call(env) ไปยังมิดเดิลแวร์ตัวถัดไป หรือตัวแอปเอง

ภายในส่วนใดๆ ของแอป Rack รวมถึงมิดเดิลแวร์ คุณสามารถเปลี่ยนการตอบสนองได้

ตัวอย่าง :

class UpcaseAll
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)

    response.upcase!

    [status, headers, response]
  end
end

นั่นเป็นวิธีที่ Rack ทำงาน 🙂

สรุป

คุณได้เรียนรู้เกี่ยวกับ Rack ซึ่งเป็นอินเทอร์เฟซที่ขับเคลื่อนการโต้ตอบระหว่างเฟรมเวิร์กเว็บและเซิร์ฟเวอร์ของ Ruby คุณยังได้เรียนรู้วิธีเขียนแอปพลิเคชัน Rack ของคุณเองเพื่อให้เข้าใจวิธีการทำงาน

หากคุณมีคำถามหรือข้อเสนอแนะโปรดแสดงความคิดเห็นด้านล่าง

ขอบคุณสำหรับการอ่าน!