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

3 วิธีในการกำหนดค่า Ruby API Wrappers ของคุณ

เมื่อคุณใช้ Ruby เพื่อห่อ API คุณต้องมีวิธีกำหนดค่า บางที wrapper อาจต้องการชื่อผู้ใช้และรหัสลับ หรืออาจเป็นแค่โฮสต์

มีหลายวิธีในการจัดการกับสิ่งนี้ แล้วควรเลือกอันไหนดี?

วิธีที่ง่ายและเป็นสากล

คุณอาจต้องการให้บริการของคุณทำเหมือนมีอยู่ทุกที่ ไม่ว่าคุณจะอยู่ที่ไหนในแอป คุณก็พร้อมใช้ มิฉะนั้น คุณจะใช้เวลาสามบรรทัดในการกำหนดค่าสำหรับทุกบรรทัดที่ใช้!

คุณสามารถทำให้การกำหนดค่าเป็นสากลโดยใช้ค่าคงที่หรือแอตทริบิวต์ของคลาส:

config/initializers/product_api.rb
ProductApi.root = "https://staging-host.example.com/"
ProductApi.user = "justin"
ProductApi.secret = "mysecret123"
app/controllers/products_controller.rb
def show
  @product = ProductApi.find(params[:id])
end

อัญมณีจำนวนมากใช้รูปแบบนี้ มันค่อนข้างง่ายในการเขียนและใช้งานง่ายมาก แต่มันมีปัญหาใหญ่อยู่บ้าง:

  • คุณสามารถมี ProductApi ได้เพียงตัวเดียวเท่านั้น .

    หากคุณต้องการใช้ Product API เป็นผู้ใช้สองคน หรือเข้าถึงเซิร์ฟเวอร์ที่ต่างกันจากแอปเดียว แสดงว่าคุณโชคไม่ดี

  • ProductApi มีข้อมูลทั่วโลกที่ง่ายต่อการเปลี่ยนแปลงโดยไม่ได้ตั้งใจ

    หากเธรดหรือส่วนหนึ่งของแอปของคุณเปลี่ยน ProductApi.user , อย่างอื่นโดยใช้ ProductApi จะแตก และนั่นก็เจ็บปวด ข้อบกพร่องที่จะติดตาม

ดังนั้น ตัวแปรคลาสจึงมีปัญหาบางอย่าง จะเกิดอะไรขึ้นถ้าคุณกำหนดค่า อินสแตนซ์ ของคลาส Product API ของคุณแทนหรือไม่

หน้าตาจะเป็นอย่างไรเมื่อใช้ #initialize ?

หากคุณใช้อินสแตนซ์ คุณจะต้องสร้างและกำหนดค่า Wrapper API เมื่อคุณต้องการ:

app/controllers/products_controller.rb
def show
  product_api = ProductApi.new(
    root: "https://staging-host.example.com/",
    user: "justin",
    secret: "mysecret123")
  @product = product_api.find(params[:id])
end

ตอนนี้คุณสามารถส่งรายละเอียดต่างๆ ไปยัง API ของคุณทุกครั้งที่ใช้งาน ไม่มีวิธีการหรือเธรดอื่นใดที่ใช้อินสแตนซ์ของคุณ คุณจึงไม่ต้องกังวลว่าจะเปลี่ยนโดยที่คุณไม่รู้ตัว

นี้ดูเหมือนดีกว่า แต่ก็ยังไม่ง่ายอย่างที่ควรจะเป็น เพราะคุณต้องกำหนดค่า API ทุกครั้ง คุณใช้มัน

ส่วนใหญ่คุณไม่สนใจว่า API ถูกตั้งค่าอย่างไร คุณแค่ต้องการใช้กับตัวเลือกที่เหมาะสม แต่เมื่อคุณทำงานกับอินสแตนซ์ ทุกส่วนของแอปที่ใช้ API จะต้องรู้วิธีกำหนดค่า

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

และรูปแบบนี้ปรากฏขึ้นตลอดเวลาในสถานที่ที่น่าสนใจ:การพัฒนา OS X และ iOS

คุณจะได้รับค่าเริ่มต้นที่ดีอย่างไร และ ความยืดหยุ่น?

จะเกิดอะไรขึ้นถ้าคุณสามารถกำหนดค่าแต่ละอินสแตนซ์ของตัวห่อ API ของคุณ แต่คุณยังมีอินสแตนซ์ "เริ่มต้น" ส่วนกลางเมื่อคุณไม่สนใจ

คุณจะเห็นรูปแบบ "defaultSomething" หรือ "sharedWhatever" นี้ใน SDK ของ iOS และ Mac OS:

[[NSURLSession sharedSession] downloadTaskWithURL:@"https://www.google.com"];

[[NSFileManager defaultManager] removeItemAtPath:...];

และคุณยังสามารถขออินสแตนซ์ของคลาสเหล่านี้ได้หากต้องการมากกว่าค่าเริ่มต้น:

NSURLSession *session = [NSURLSession sessionWithConfiguration:...];

NSFileManager fileManager = [[NSFileManager alloc] init];

คุณสามารถสร้างสิ่งนั้นใน Ruby ด้วย default_api วิธีการเรียน:

app/controllers/products_controller.rb
def show
  @product = ProductApi.default_product_api.find(params[:id])
end

...

def show_special
  special_product_api = ProductApi.new(
    root: "https://special-product-host.example.com/"
    user: "justin"
    secret: "mysecret123")
  @special_product = special_product_api.find(params[:id])
end

และการใช้งานอาจมีลักษณะดังนี้:

class ProductApi
  def initialize(root:, user:, secret:)
    @root, @user, @secret = root, user, secret
  end

  def self.default_api
    @default_api ||= new(
      root: ENV['PRODUCT_API_ROOT'],
      user: ENV['PRODUCT_API_USER'],
      secret: ENV['PRODUCT_API_SECRET'])
  end

  def find(product_id)
    ...
  end
end

ที่นี่ ฉันใช้ตัวแปรสภาพแวดล้อมใน default_api แต่คุณยังสามารถใช้ไฟล์ปรับแต่งได้ และคุณสามารถเปลี่ยน ||= เพื่อใช้ที่จัดเก็บเธรดหรือร้องขอในเครื่องแทน

แต่นี่เป็นการเริ่มต้นที่ดี

อัญมณีส่วนใหญ่ที่ฉันเคยเห็น เช่น Twitter gem จะช่วยให้คุณกำหนดค่าและสร้างแต่ละอ็อบเจ็กต์ API เมื่อคุณต้องการ นี่เป็นวิธีแก้ปัญหาที่ดี (แม้ว่าปกติฉันจะเห็นคนกำหนดสิ่งเหล่านี้ให้กับ globals อยู่แล้ว )

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