2010-01-07 25 views
48

Tôi đã xem Best practices for API versioning?, nhưng không hoàn toàn bị thuyết phục về câu trả lời, vì vậy tôi hỏi phần phiên bản một lần nữa với một ví dụ cụ thể hơn. Tôi đang có hai URI (một phiên bản là một phần của URI và một không có):REST api versioning (chỉ phiên bản đại diện, không phải bản thân tài nguyên)

http://xxxx/v1/user/123 -> favored solution in discussed thread 
http://xxxx/user/123    

Tôi đang nghi ngờ liệu liên kết đầu tiên có thể đưa ra ý tưởng về REST hay không. Tôi thấy http://xxxx/v1/user/123 gây nhầm lẫn vì nó cho thấy rằng sẽ có một phiên bản api cao hơn vào một ngày nào đó như http://xxxx/v2/user/123. Nhưng điều này không có ý nghĩa trong các thuật ngữ REST, bản thân api là HTTP 1.0 hoặc 1.1, đã được gửi bên trong yêu cầu HTTP. Khung nhìn trung tâm tài nguyên REST này khác rất nhiều so với các giao diện api khác như SOAP hoặc giao diện Java (nơi mà thông thường có các phiên bản api trong các tên đủ điều kiện).

Tại REST điều duy nhất trong đó phiên bản có ý nghĩa là sự biểu diễn của tài nguyên đó (ví dụ: các trường mới được thêm hoặc xóa). phiên bản này thuộc về một phần của nội dung đàm phán như:

http://xxx/user/123 + HTTP 'Accept' Header -> Content negotation through header 
http://xxx/user/123?v=1     -> for perma-links/hyperlinks 

Người ta cũng có thể lập luận rằng đó là phiên bản nội dung đàm phán có thể là một phần của URI bên con đường, nhưng tôi thấy nó phản trực giác, bởi vì bạn có thể kết thúc với các URI khác nhau cho cùng một tài nguyên và phải duy trì chuyển hướng tại một số điểm.

Để tổng hợp: Trong các URI REST không có phiên bản api, chỉ phiên bản trình bày của tài nguyên. Phiên bản đại diện-thông tin thuộc về thương lượng nội dung (như queryParam hoặc HTTP 'Chấp nhận').

Bạn nghĩ sao? Bạn sẽ không đồng ý với những điều gì?

+1

chỉ là một điều nhỏ cần thêm. chỉ showstopper với tôi và sử dụng ... v1/style là, khi bạn không có sự cân bằng tải dưới sự kiểm soát và không thể xác định hướng đến các máy chủ ứng dụng trên cơ sở tiêu đề HTTP trên frontmachines (-> thương lượng nội dung là một phần của tiêu đề HTTP). Thường thì tiêu chuẩn là sử dụng đường dẫn URL. và trong các khung công tác trên web, tôi có thể nghĩ rất khó để xác định các điểm cuối ánh xạ yêu cầu bên trong bộ điều khiển trên cơ sở tiêu đề HTTP thay vì đường dẫn. –

Trả lời

35

Tôi hoàn toàn đồng ý; một URI thể hiện bản sắc, danh tính không thay đổi khi một phiên bản mới được giới thiệu. Có thể có các URI mới cho các khái niệm bổ sung, tất nhiên, và các URI hiện có có thể chuyển hướng ... nhưng bao gồm một "v2" trong URI có mùi RPCish với tôi.

Lưu ý rằng điều này không liên quan gì đến REST, thực sự, như từ quan điểm REST, tất cả chỉ là các ký tự.

+2

có, nó chỉ là ký tự. nhưng nó là tốt để có URI tốt đẹp/nhất quán, bởi vì họ là một phần của giao diện người dùng api chương trình chống lại. –

+1

đây là một ví dụ khác về cách không sử dụng phiên bản trong url của bạn, http://blog.steveklabnik.com/2011/07/03/nobody-understands-rest-or-http.html – kidbrax

+1

Điều này đã được trả lời trong chi tiết hơn trước đây tại đây http://stackoverflow.com/q/389169/104261. –

1

tôi thấy http://xxxx/v1/user/123 khó hiểu vì nó cho thấy rằng có sẽ là một api-phiên bản cao hơn một ngày nào đó như http://xxxx/v2/user/123

Nó không gợi ý rằng - tuy nhiên bạn có khả năng đó trong tương lai.

Nhưng điều này không có ý nghĩa trong REST ngữ, phiên bản api chính nó là HTTP 1.0 hoặc 1.1, mà đã được gửi bên trong yêu cầu HTTP.

Phiên bản API của bạn và phiên bản HTTP mà bạn đang sử dụng để thực hiện yêu cầu không nhất thiết phải bằng nhau.

Người ta cũng có thể lập luận rằng phiên bản như vậy nội dung đàm phán có thể là một phần của URI bên con đường, nhưng tôi thấy nó phản trực giác, bởi vì bạn có thể end-up với các URI khác nhau cho các cùng một tài nguyên và phải duy trì chuyển hướng tại một số điểm.

Không sao để có phiên bản dưới dạng tham số URI như bạn đã minh họa.

http://xxx/user/123?v=1 -> cho perma-liên kết/siêu liên kết

+0

cảm ơn các gợi ý. nhưng một câu hỏi: nói cụm từ REST, ý kiến ​​của bạn làm cho phiên bản 'API của BẠN' là gì? vì tôi không thấy phiên bản bên trong ứng dụng REST bên cạnh giao thức HTTP và biểu diễn tài nguyên. –

+4

Tôi thường bắt đầu REST API tại v1. Phiên bản api về cơ bản là một hợp đồng/giao diện của những gì khách hàng có thể đồng ý. Nếu tôi thay đổi giao diện/api, và có lẽ tôi phá vỡ hợp đồng đó, tôi có thể tăng lên phiên bản v2 hoặc v1.1 - Tuy nhiên, không có lý do nào cho phiên bản của tôi phản ánh phiên bản của ứng dụng HTTP thực hiện yêu cầu. cái đó có giúp ích không? –

9

Đối với những gì nó có giá trị, tôi đồng ý với bạn Manuel. Bạn có thể thấy lý do của tôi trong câu hỏi này How to version REST URIs

Có rất nhiều người dường như không đồng ý nhưng tôi sẽ không lo lắng. Url của bạn trông như thế nào thực sự không có tác động lớn đến khách hàng của bạn miễn là bạn tôn trọng ràng buộc siêu văn bản.

+2

+1 "URL của bạn trông như thế nào thực sự không có tác động lớn đến khách hàng của bạn miễn là bạn tôn trọng ràng buộc siêu văn bản". Điều này không thể được nhấn mạnh đủ. –

+0

+1 cho "URL của bạn trông như thế nào thực sự không có tác động lớn đến khách hàng của bạn miễn là bạn tôn trọng ràng buộc siêu văn bản" – andy

10

Bạn có thể nghe tiêu đề yêu cầu HTTP X-API-Version HTTP. Nếu tiêu đề tồn tại thì máy chủ phải sử dụng phiên bản API đó. Nếu tiêu đề không tồn tại, máy chủ có thể sử dụng phiên bản API mới nhất.

> GET /user/123 HTTP/1.1 
> Host: xxx 
> X-API-Version: >=1.5.1, <2.0.0 
> Accept: application/json 
> 

< HTTP/1.1 200 OK 
< X-API-Version: 1.6.12 
< 
< { "user": { "id": 123, "name": "Bob Smith" } } 
< 
+0

Nhưng điều này không phải chịu rủi ro mà các trung gian khác nhau (proxy, cache) có thể hoặc không thể tôn trọng tiêu đề đó và thậm chí có thể không vượt qua nó? – verveguy

+0

Có thể - nó chắc chắn sẽ phụ thuộc vào proxy. – yfeldblum

+0

Quá tệ khi tiêu đề bị xóa trong một số trường hợp. – neoneye

2

Tôi đồng ý rằng bạn không muốn thấy các phiên bản trong URI của tài nguyên được trình bày trong API của bạn. Điều đó khiến chúng không "mát mẻ". Cũng đồng ý rằng đó là các đại diện có nhiều khả năng thay đổi nhất.

Tuy nhiên, sau đó, câu hỏi sẽ xảy ra khi bạn thay đổi nội dung của một đại diện cụ thể. Ví dụ nếu JSON đại diện ban đầu của bạn của một frobnitz là

{"x": "bam", "y": "hello"} 

và bạn muốn thêm một "z" lĩnh vực bạn có thể cảm thấy rằng khách hàng nên có một số nhận thức rằng chúng tôi bây giờ phiên bản 2 của một số loại lược đồ dữ liệu.

Tôi không chắc chắn về điều đó. Tôi nghĩ bạn có một vài tùy chọn:

  • Làm cho khách hàng của bạn linh hoạt khi đối mặt với một đại diện thay đổi nhẹ nhàng. Trong ví dụ trên, chúng tôi vẫn đang tạo một từ điển JSON.
  • Nếu bạn phải, hãy đặt một phiên bản trong chính biểu diễn (trường phiên bản trong ví dụ này). Bằng cách làm như vậy, bạn đang khai báo hiệu quả một biểu diễn con bên trong loại nội dung JSON. Tôi nghĩ đó là khá hạn chế mặc dù.
  • Sử dụng các loại MIME của riêng bạn và phiên bản chúng: application/x-my-special-json1.0, ứng dụng/x-my-special-json1.1 của tôi. Điều này cho phép bạn phiên bản các đại diện của bạn độc lập với nhau. Một lần nữa, với điều này bạn đang thực hiện một nhu cầu đáng kể về khách hàng của bạn để biết những gì đang xảy ra.

Nói chung, tôi nghĩ bạn muốn tối ưu hóa API và đại diện cho khách hàng mà bạn chưa tự mình phát minh; những thứ mà người khác sẽ tạo ra khi khám phá tài nguyên của bạn. Tôi tin rằng điều này là hữu ích ngay cả trong trường hợp khi bạn đang làm một cái gì đó là riêng tư bởi vì nó xây dựng trong một hạn chế thiết kế hữu ích sẽ giúp làm cho hệ thống của bạn mạnh mẽ hơn.

1

cách tiếp cận khác có thể là để nói rằng "một đại diện có nhiều API":

http://xxx/user/123/api/1.json 

Và nếu bạn muốn, bạn có thể trở lại các đại diện bằng cách sử dụng API mới nhất khi yêu cầu như thế này:

http://xxx/user/123.json 

Cá nhân tôi thích các giải pháp khác tốt hơn nhưng đây là một cách tiếp cận khác mà tôi chưa từng thấy ở đây.

0

Đối với REST, phần lớn câu trả lời quên là phần tử dữ liệu. Tôi cho rằng nhiều phiên bản API vẫn chia sẻ cùng một lớp dữ liệu. Điều này có nghĩa là lớp dữ liệu buộc bạn phải suy nghĩ theo cách tương thích ngược. Những thay đổi lớn phải được thực hiện chỉ có thể nếu API của bạn thay đổi theo cách tương thích ngược. Trong thực tế, điều này có nghĩa là các thuộc tính bổ sung được thêm vào âm thầm cho các thực thể của bạn trong khi sử dụng tính năng ngừng sử dụng theo ngày trong tài liệu API của bạn để cho biết khi nào một thứ sẽ bị xóa. Lý tưởng nhất là bạn sử dụng lược đồ đăng ký với địa chỉ email của người dùng khóa API của bạn, vì vậy bạn có thể thông báo cho họ về việc không dùng nữa trong phạm vi nhất định (a la Facebook) .Tại sao, tôi không nghĩ bạn cần chỉ định phiên bản ở bất kỳ đâu.

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