2011-07-23 34 views
6

Tôi hiện đang trong quá trình thiết kế API được phiên bản cho một trang web mới. Tôi hiểu làm thế nào để không gian tên các tuyến đường nhưng tôi bị mắc kẹt trên cách tốt nhất để thực hiện các phương pháp phiên bản trong một mô hình.API Phiên bản trong các ứng dụng web

Các mẫu mã bên dưới đang sử dụng khung đường ray nhưng nguyên tắc của vấn đề phải nhất quán giữa hầu hết các khung web.

Các tuyến đường hiện giống như thế:

MyApp::Application.routes.draw do 
    namespace :api do 
    namespace :v1 do 
     resources :products, :only => [:index, :show] 
    end 
    end 
end 

Và bộ điều khiển:

class Api::V1::ProductsController < V1Controller 
    respond_to :json, :xml 

    def index 
    respond_with @products = Product.scoped 
    end 

    def show 
    respond_with @product = Product.find(params[:id]) 
    end 
end 

Vì vậy, rõ ràng là chúng tôi chỉ phơi bày các thuộc tính có sẵn trên sản phẩm ở đây, giải pháp này hoạt động tuyệt vời nếu bạn' sẽ chỉ có một phiên bản của API. Điều gì xảy ra khi bạn muốn phát hành V2 và V2 cần phải triển khai lại cách tên của Sản phẩm được hiển thị (trong khi vẫn duy trì khả năng tương thích ngược với V1 - ít nhất là trong thời gian ngắn)?

Theo như tôi thấy nó, bạn có một vài tùy chọn ...

  1. Drop hỗ trợ cho V1 ngay lập tức và đối phó với bụi phóng xạ (giải pháp tồi tệ nhất có thể)
  2. Bạn bắt đầu trọng các to_ [định dạng ] phương pháp (Tôi khá chắc chắn bạn làm điều này với as_ [định dạng] nhưng đó là bên cạnh điểm) để bao gồm một thuộc tính mới ... name_2 - điều này có vẻ như câm
  3. Thực hiện một số loại lớp proxy chịu trách nhiệm chỉ hiển thị các phương pháp mà chúng tôi đang theo dõi
  4. Hãy quan điểm xử lý tạo ra một số loại băm mà các bộ điều khiển phiên bản và gọi to[format] trên ...

Ba và Bốn là những người duy nhất mà tôi có thể thực sự nghĩ rằng làm cho bất kỳ loại cảm giác ... Ba sẽ giống như:

# model 
class Api::V1::Product < Struct.new(:product) 
    def to_json 
    attributes.to_json 
    end 

    def to_xml 
    attributes.to_xml 
    end 

private 
    def attributes 
    {:name => product.name} # add all the attributes you want to expose 
    end 
end 

# Controller 
class Api::V1::ProductsController < V1Controller 
    respond_to :json, :xml 

    def show 
    respond_with @product = Api::V1::Product.new(Product.find(params[:id])) 
    end 
end 

Những người khác đã làm gì trong quá khứ?

Trả lời

6

Thay vì một ứng dụng phân phối V1 và V2 và V ... bạn triển khai một ứng dụng cho mỗi phiên bản. Một ứng dụng sẽ trả lời api.domain.com/v1, sau đó ứng dụng khác sẽ trả lời api.domain.com/v2 và v.v.

Đó là cách các ứng dụng hướng dịch vụ được tổ chức tốt nhất, mỗi dịch vụ phải được cách ly, triển khai độc lập.

Phục vụ tất cả các phiên bản từ một ứng dụng duy nhất đánh bại mục đích thiết kế hướng dịch vụ, vì mỗi khi bạn thực hiện thay đổi trong một dịch vụ, bạn sẽ cần phải thử nghiệm và triển khai cho tất cả.

+0

Đây là giải pháp thực sự tốt - điều mà tôi chưa từng nghĩ đến ... – Coop

-1

Tôi nghĩ bạn có thể đang thiết kế kỹ hơn API của mình nếu bạn có kế hoạch tạo các phiên bản riêng biệt. Miễn là bạn không bao giờ xóa URL và thuộc tính về sau, thì khách hàng cũ có thể tiếp tục sử dụng API của bạn. Chỉ cần sử dụng v1, v2, v.v. như một cách để tách biệt khách hàng khi các API đang làm việc xung quanh một lỗi hoặc quirk.

Nếu bạn thay đổi kiến ​​trúc cơ bản ngoài những gì API ban đầu có thể hỗ trợ, thì tôi đồng ý bạn sẽ cần tạo proxy cho nền tảng cũ nếu bạn định hỗ trợ khách hàng cũ. Đối với hệ thống mới, tôi sẽ tạo một máy chủ điểm cuối hoàn toàn mới như @Nerian đề xuất.

Các vấn đề liên quan