2014-11-10 52 views
21

Hãy nói rằng tôi có một nguồn tài nguyên Jersey REST của đơn giản như sau:Có đúng không khi trả về 404 khi không tìm thấy tài nguyên REST?

@Path("/foos") 
public class MyRestlet 
     extends BaseRestlet 
{ 

    @GET 
    @Path("/{fooId}") 
    @Produces(MediaType.APPLICATION_XML) 
    public Response getFoo(@PathParam("fooId") final String fooId) 
      throws IOException, ParseException 
    { 
     final Foo foo = fooService.getFoo(fooId); 

     if (foo != null) 
     { 
      return Response.status(Response.Status.OK).entity(foo).build(); 
     } 
     else 
     { 
      return Response.status(Response.Status.NOT_FOUND).build(); 
     } 
    } 

} 

Dựa trên mã ở trên, là nó đúng để trả lại trạng thái NOT_FOUND (404), hay tôi nên được trở 204, hoặc nhiều hơn một số khác mã thích hợp?

Rất cám ơn trước!

Trả lời

27

Phản hồi 404 trong trường hợp này khá điển hình và dễ sử dụng cho người dùng API.

Một vấn đề là khách hàng khó có thể biết được họ có 404 do thực thể cụ thể không được tìm thấy hay do vấn đề về cấu trúc trong URI. Trong ví dụ của bạn, /foos/5 có thể trả lại 404 vì foo có id = 5 không tồn tại. Tuy nhiên, /food/1 sẽ trả lại 404 ngay cả khi foo có id=1 tồn tại (vì foos bị viết sai chính tả). Nói cách khác, 404 có nghĩa là URI được xây dựng kém hoặc tham chiếu đến một tài nguyên không tồn tại.

Một vấn đề khác phát sinh khi bạn có URI tham chiếu nhiều tài nguyên. Với phản hồi 404 đơn giản, máy khách không biết tài nguyên được tham chiếu nào không được tìm thấy.

Cả hai vấn đề này có thể được giảm nhẹ một phần bằng cách trả lại thông tin bổ sung trong nội dung phản hồi để cho người gọi biết chính xác những gì không được tìm thấy.

+1

tôi muốn thêm rằng trong trường hợp '/ food/1' trả về 404 vì url đó không tồn tại, đó là lỗi của khách hàng (anh ấy đã nhập sai url) và do đó không phải vấn đề của bạn –

+9

@TimCastelijns Tôi đồng ý đó là lỗi của khách hàng. Tuy nhiên, nếu khách hàng là khách hàng của bạn thì nó sẽ trở thành vấn đề của bạn (họ sẽ lấy điện thoại và gọi cho ai đó). Nếu chúng tôi có thể giúp khách hàng sử dụng API mà không gặp phải nhiều thất vọng, tất cả chúng ta đều thắng. – Rob

+1

Nếu bạn đã cung cấp cho khách hàng tài liệu API thích hợp, đó chắc chắn là lỗi của họ ;-) nhưng tôi nhận được điểm của bạn –

16

Có, khá phổ biến để trả lại 404 cho tài nguyên không được tìm thấy. Cũng giống như một trang web, khi nó không được tìm thấy, bạn nhận được một 404. Nó không chỉ là REST, mà là một tiêu chuẩn HTTP.

Mọi tài nguyên phải có vị trí URL. URL không cần tĩnh, chúng có thể là templated. Vì vậy, có thể cho URL được yêu cầu thực tế không có tài nguyên. Đó là nhiệm vụ của máy chủ để phân tích URL từ mẫu để tìm kiếm tài nguyên. Nếu họ tài nguyên không tồn tại, sau đó nó "Not Found"

Dưới đây là từ HTTP 1.1 spec

404 Not Found

Các máy chủ đã không tìm thấy bất cứ điều gì phù hợp với các yêu cầu-URI . Không có dấu hiệu nào được đưa ra cho dù tình trạng này là tạm thời hay vĩnh viễn. Mã trạng thái 410 (Gone) NÊN được sử dụng nếu máy chủ biết, thông qua một số cơ cấu cấu hình nội bộ, rằng một tài nguyên cũ là vĩnh viễn không có sẵn và không có địa chỉ chuyển tiếp. Mã trạng thái này thường được sử dụng khi máy chủ không muốn tiết lộ chính xác lý do yêu cầu bị từ chối hoặc khi không có phản hồi nào khác được áp dụng.


Dưới đây là cho 204

204 Không có nội dung

Các máy chủ đã hoàn thành các yêu cầu nhưng không cần phải trả lại một thực thể cơ thể, và có thể muốn quay trở lại cập nhật metainformation. Câu trả lời CÓ THỂ bao gồm các biến thể mới hoặc được cập nhật dưới dạng các tiêu đề thực thể, mà nếu NÊN hiện tại được liên kết với biến thể được yêu cầu.

Nếu ứng dụng khách là tác nhân người dùng, KHÔNG NÊN thay đổi chế độ xem tài liệu của tài liệu đó khiến cho yêu cầu được gửi đi. Phản hồi này chủ yếu nhằm cho phép đầu vào cho các hành động diễn ra mà không gây ra thay đổi đối với chế độ xem tài liệu đang hoạt động của tác nhân người dùng, mặc dù bất kỳ biến thể mới hoặc cập nhật nào NÊN được áp dụng cho tài liệu hiện có trong chế độ xem đang kích hoạt của tác nhân người dùng.

Phản hồi 204 KHÔNG PHẢI bao gồm nội dung thư, do đó luôn bị chấm dứt bởi dòng trống đầu tiên sau trường tiêu đề.

Thông thường 204 sẽ được sử dụng khi đại diện được cập nhật hoặc tạo và không cần phải gửi lại phản hồi. Trong trường hợp POST, bạn có thể gửi lại vị trí của tài nguyên mới được tạo. Một cái gì đó như

@POST 
@Path("/something") 
@Consumes(...) 
public Response createBuzz(Domain domain, @Context UriInfo uriInfo) { 
    int domainId = // create domain and get created id 
    UriBuilder builder = uriInfo.getAbsolutePathBuilder(); 
    builder.path(Integer.toString(domainId)); // concatenate the id. 
    return Response.created(builder.build()).build(); 
} 

Các created(URI) sẽ gửi lại phản ứng với URI mới được tạo ra trong Location tiêu đề.


Thêm vào phần đầu tiên. Bạn chỉ cần ghi nhớ rằng mọi yêu cầu từ một khách hàng là một yêu cầu để truy cập một tài nguyên, cho dù đó chỉ là GET nó, hoặc cập nhật với PUT. Và một tài nguyên có thể là bất cứ thứ gì trên máy chủ. Nếu tài nguyên không tồn tại, thì một phản ứng chung sẽ là nói với khách hàng rằng chúng ta không thể tìm thấy tài nguyên đó.

Để mở rộng ví dụ của bạn. Giả sử FooService accsses DB. Mỗi hàng trong cơ sở dữ liệu có thể được coi là một tài nguyên. Và mỗi người trong số những hàng (tài nguyên) có một URL duy nhất, như foo/db/1 có thể xác định vị trí một hàng với một khóa chính 1. Nếu id không thể được tìm thấy, sau đó nguồn"Not Found"

+1

Cảm ơn câu trả lời của bạn! Nó tuyệt vời vì nó khá rộng. Cả hai câu trả lời đều rất hữu ích, nhưng, thật không may, tôi chỉ có thể chấp nhận một câu trả lời ... :( – carlspring

+1

khoảng 400? – Belun

+0

@Belun Tại sao 400? –

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