2009-05-08 33 views
43

Đối với trang web tôi đang làm việc, chúng tôi đang trong quá trình cải thiện URL của chúng tôi cho một loại tài nguyên - cụ thể, chuyển từ ID số sang các chuỗi mô tả duy nhất. Một ví dụ tương tự sẽ được chuyển từ việc xác định người dùng bằng ID cơ sở dữ liệu số để xác định chúng bằng tên người dùng (không phải trường hợp cụ thể của chúng tôi, nhưng là analagous). Vì vậy, một URL để truy cập thông tin của người dùng sử dụng để trông giống như:REST - hỗ trợ nhiều số nhận dạng có thể

/users/48573 

Và bây giờ có vẻ như

/users/thisisausername. 

Vấn đề duy nhất là chúng tôi vẫn cần để có thể lấy chúng thông qua ID số bằng cách nào đó , cho người tiêu dùng cũ của API. Chúng tôi không cần các URL REST để chuyển hướng (ví dụ: /users/48573 không được chuyển hướng đến /users/thisisausername), chúng tôi chỉ cần một phương pháp để có được dữ liệu phù hợp bằng cách sử dụng số nhận dạng cũ. Giải pháp phải cung cấp một cách thay thế để truy cập thông tin người dùng (tiện lợi bao gồm mã định danh, tên người dùng mới) theo ID hoặc chỉ truy cập tên người dùng theo ID. Một số giải pháp có thể có thể là:

  • Sử dụng nút để chỉ định một số phương pháp nhận dạng thay thế, ví dụ: /users/byid/48573
  • Sử dụng thông số truy vấn để chỉ định một số phương pháp nhận dạng thay thế, ví dụ: /users/48573?fetchby=id hoặc /users/48573?byid=true
  • Xử lý tên người dùng theo id làm tài nguyên khác, ví dụ: /identifiers/username/48573

Điều nào trong số này (nếu có) gần nhất với REST phù hợp? Làm thế nào bạn sẽ đối phó với vấn đề này?

+4

tôi đã kết thúc thực hiện truy cập thông qua các lĩnh vực phi chính-identifier như một tìm kiếm. Giải pháp này cho phép tìm nạp nhiều loại tài nguyên qua nhiều trường, trong khi vẫn duy trì một loại làm số nhận dạng chính. Để nhất quán, API "tìm kiếm" trả về danh sách. Vì vậy, cách chính thức để truy cập người dùng là: /người dùng/thisisausername và tiếp cận bởi ID, ta có:? /người dùng id = 48.573 Tương tự như vậy, chúng ta có thể tìm kiếm trên một số lĩnh vực khác nhau , như trong: /người dùng? firstName = Kelly Cảm hứng từ: http://jwyseur.blogspot.com/2008/12/uri-design-for-rest.html (xem "tìm kiếm tài nguyên") –

+0

Vì vậy, bạn punted vào bộ nhớ đệm? Tôi có cùng vấn đề với bạn, nhưng không thể giải quyết vấn đề thông qua các tham số truy vấn loại bỏ một trong những lợi ích chính của API REST. Tôi thích đề xuất đầu tiên của bạn có dấu đầu dòng ... – HDave

Trả lời

10

Tùy chọn đầu tiên của bạn có lẽ là tốt nhất.

Tìm kiếm người dùng bằng ID:

/users/id/48573 

Tìm kiếm người dùng bằng tên viết tắt:

/users/name/thisisausername 

Nếu họ rời ra rằng tham số đường, bạn luôn có thể mặc định sang định dạng tên ngắn mới của bạn.

Một tùy chọn khác mà tôi đã thấy khá một chút là sử dụng tham số truy vấn như sau:

/users?id=48573 
/users?name=thisisausername 

Tôi nghĩ là người đầu tiên trông sạch hơn chút và dễ đọc hơn.

+0

ngắn và cho điểm, hoàn hảo! –

-3

Tôi muốn xem xét đủ điều kiện chuỗi đi kèm hậu tố tùy chọn:

/users/48573/id 

/users/48573/name 

Nếu bạn nhận được một chuỗi mà không có hậu tố:

/users/48573 

sau đó bạn kiểm tra các chuỗi và xem nếu nó là một ID hoặc Tên.

Nếu bạn chỉ nhận được một ID hợp lệ nhưng không phải là một tên thì đó là một hồi bằng ID tương đương với:

/users/48573/id 

Nếu bạn chỉ có được một tên trở lại thì đó là một hồi theo Tên tương đương với:

/users/48573/name 

Nếu bạn có thể lấy giá trị bằng ID hoặc tên sau đó bạn quay trở lại một lỗi 300 phản hồi và trở lại liên kết với cả hai possiblities cho khách hàng:

/users/48573/id 

/users/48573/name 

Người tiêu dùng cũ tiếp tục hoạt động 'nguyên trạng' ngoại trừ thỉnh thoảng xảy ra các cặp ID/tên trùng lặp nơi họ nhận được lỗi phản hồi 300 mới.

+7

Đây không phải là REST. Đây chỉ là RPC. – aehlke

-3

API của bạn không phải là RESTful nếu đây là vấn đề. Để quote Roy Fielding:

REST API không được xác định tên hoặc phân cấp tài nguyên cố định (khớp nối rõ ràng giữa máy khách và máy chủ). Máy chủ phải có quyền tự do kiểm soát không gian tên của chính họ. Thay vào đó, cho phép các máy chủ hướng dẫn khách hàng về cách xây dựng các URI thích hợp, chẳng hạn như được thực hiện trong các biểu mẫu HTML và các mẫu URI, bằng cách xác định các hướng dẫn đó trong các kiểu phương tiện và các mối quan hệ liên kết. [Thất bại ở đây ngụ ý rằng các máy khách giả định một cấu trúc tài nguyên do thông tin ngoài băng tần, chẳng hạn như một tiêu chuẩn miền cụ thể, là định hướng dữ liệu tương đương với khớp nối chức năng của RPC].

API REST nên được nhập mà không có kiến ​​thức trước ngoài URI ban đầu (dấu trang) và tập hợp các loại phương tiện được chuẩn hóa phù hợp với đối tượng dự kiến ​​(nghĩa là mọi khách hàng có thể sử dụng API) . Từ thời điểm đó, tất cả các quá trình chuyển đổi trạng thái ứng dụng phải được thúc đẩy bởi sự lựa chọn của khách hàng về các lựa chọn do máy chủ cung cấp có trong các đại diện đã nhận hoặc ngụ ý bởi thao tác của người dùng đối với các đại diện đó. Việc chuyển đổi có thể được xác định (hoặc bị giới hạn bởi) kiến ​​thức của khách hàng về các loại phương tiện và cơ chế truyền thông tài nguyên, cả hai cơ chế này đều có thể được cải tiến nhanh chóng (ví dụ: mã theo yêu cầu). [Thất bại ở đây ngụ ý rằng thông tin ngoài băng tần đang thúc đẩy tương tác thay vì siêu văn bản.]

+1

Đây không phải là câu trả lời cho câu hỏi của anh ấy. REST API có thể hỗ trợ HATEOAS cả ngày và các nhà phát triển máy chủ vẫn cần phải lo lắng về các vấn đề của thiết kế URI. – HDave

28

Tôi nghĩ rằng thêm một đoạn đường dẫn/tiền tố là câu trả lời hay nhất. Vì đây là các khóa phụ duy nhất, điều này không giống như tìm kiếm (trả về một tập hợp các mục), vì vậy việc sử dụng tham số truy vấn (không được lưu trong bộ nhớ cache) dường như không phải là lựa chọn tốt nhất.

Cá nhân, tôi có kế hoạch để sử dụng một tiền tố phân khúc đường giới hạn bởi "=", như "name =" hay "email =":

user/123456 
user/name=john.doe 
user/[email protected] 

Đây là chức năng tương đương để thêm một đoạn đường dẫn (ví dụ: " người dùng/tên/john.doe "), nhưng cảm thấy với tôi như nó bản đồ chặt chẽ hơn với mô hình khái niệm. Tất nhiên, đây là một chi tiết không đáng kể, vì RESTful APIs không nên chỉ định một cấu trúc URI cố định.

Không sử dụng tham số truy vấn cũng cho phép phụ nguồn lực để được truy cập một cách tự nhiên:

user/name=john.doe/inbox/df87bhJXrg63 

Khung như Java của JAX-RS hỗ trợ sử dụng bất cứ điều gì delimiter bạn muốn:

@GET 
@Path("user/{id}") 
User getUser(@PathParam("id") UUID id); 

@GET 
@Path("user/name={name}") 
User getUserByName(@PathParam("name") String name); 

@GET 
@Path("user/email={email}") 
User getUserByEmail(@PathParam("email") String email); 
+2

Đây là một cách tiếp cận thú vị mà tôi chưa từng thấy trước đây. Nó giải quyết vấn đề một cách độc đáo, nhưng tôi không thể vượt qua sự thật rằng nhìn thấy dấu bằng bên ngoài các tham số truy vấn có vẻ như nó sẽ gây nhầm lẫn ... – HDave

+4

Plus, nó không phải là rất yên tĩnh. những gì, chính xác, là tên bộ sưu tập = john.doe? Đối với tôi, nó phải là thông số ma trận: người dùng; name = john.doe/inbox/df87 ... http://blog.2partsmagic.com/restful-uri-design/ – Maladon

+0

@Maladon Tôi nghĩ bạn thiếu điểm. 'name = john.doe' không phải là một bộ sưu tập, vì' name' là một định danh duy nhất. Chúng tôi đang tìm chính xác một đối tượng hoặc một lỗi. 'user; name = john.doe' trông giống như tìm kiếm. Tôi hy vọng nó sẽ trả về cùng một biểu diễn như 'user', là một tập hợp. –

0

Khá một câu hỏi cũ nhưng Tôi đã có cùng và finnaly tìm thấy các giải pháp: sử dụng regex trong param đường dẫn của bạn.

Đây là cách tôi mã hóa mà trường hợp sử dụng

@GET 
@Path("/{id : \\d+}") 
@Produces(APPLICATION_JSON) 
public Response getById(@PathParam("id") long id) { 
<<your code>> 
} 

@GET 
@Path("/{name}") 
@Produces(APPLICATION_JSON) 
public Response getByName(@PathParam("name") String name) { 
<<your code>> 
} 
+1

Điều gì sẽ xảy ra nếu tên của người dùng là số? Nếu người dùng có thể chọn tên của mình một cách tự do và quyết định chỉ sử dụng một số phương pháp tiếp cận của bạn không thành công. –

+0

nó không thành công hay không. Bạn phải thực hiện điều khiển trên yêu cầu tạo (POST) và có thể từ chối chỉ tên số. – Javathought

+0

@@ POST Phản hồi công khai tạo (@Valid Người dùng thành viên) và chú thích mô hình của bạn bằng xác thực bean. Ví dụ: phải bắt đầu bằng chữ cái viết hoa, 50 chữ cái tối đa @@ Mẫu (regexp = "[AZ] [a-zA-Z_0-9-] {0,49}", message = "tên không hợp lệ") riêng tư Tên chuỗi; – Javathought

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