Thực hành tốt nhất cho lệnh gọi API REST với nhiều tham số


11

Tôi có API REST với các hoạt động GET nhận danh sách tham số (dài) (ví dụ 8 tham số). Mục đích của hoạt động này là tìm kiếm và lọc các yếu tố.

Đó là cách thực hành tốt nhất để quản lý kịch bản này?:

(1) Nhận danh sách các tham số?:

public ResultType Get(int p1, int p2, string p3...) { ... }

(2) Hoặc nhận một đối tượng gói gọn các tham số này ?:

public class MyClass
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Z { get; set; }
}

public ResultType Get(MyClass parameter) { ... }

Hãy suy nghĩ trong một kịch bản thương mại điện tử mà bạn muốn tìm kiếm và lọc "sản phẩm" theo tên, mô tả, danh mục, nhãn hiệu, kiểu máy, giá cả, v.v.


1
Vị trí là một định danh ít hơn một tên thích hợp cho một giá trị.
SD

Tại sao bạn có 8 tham số? Họ làm gì? Có một số logic quyết định liên quan (và nó là một mớ hỗn độn)? Bạn có thể chia api / phương thức đó thành nhiều phương thức có 3 hoặc 4 tham số không?
Filip Milovanović

1
8 tham số chỉ là một ví dụ. Hoạt động Get của tôi là một phương pháp "tìm kiếm". Hãy suy nghĩ trong một kịch bản thương mại điện tử mà bạn muốn tìm kiếm và lọc "sản phẩm" theo tên, mô tả, danh mục, nhãn hiệu, kiểu máy, giá cả, v.v ... Tôi đã chỉnh sửa câu hỏi để thêm ngữ cảnh
Jose Alonso Monge

Câu trả lời:


10

Tôi có API REST với các hoạt động GET nhận danh sách (dài) các tham số>. Đó là cách thực hành tốt nhất để quản lý kịch bản này?

AFAIK, không có thực hành tốt nhất được thiết lập vững chắc (xin lỗi). Tuy nhiên, người ta có thể đưa ra một số khuyến nghị:

  • Cố gắng tránh sử dụngPOST (thay vì GET) nếu yêu cầu an toàn (nghĩa là không có tác dụng phụ, đặc biệt là không sửa đổi dữ liệu). Nếu các tham số rất lớn, bạn có thể phải sử dụng POSTđể khắc phục các giới hạn về độ dài, nhưng thường thì đây không phải là vấn đề (hầu hết các phần mềm hỗ trợ URL khá dài) và các yêu cầu an toàn nên sử dụng GETđể cho phép tối ưu hóa như lưu trữ và tìm nạp trước.

  • Nếu bạn sử dụng GET, bạn phải gửi tham số của mình dưới dạng tham số URL 1) . Trong tình huống đó, giải pháp tự nhiên và phổ biến là sử dụng danh sách các tham số , vì vậy đó là những gì tôi khuyên dùng. Có, danh sách sẽ dài, nhưng API REST (có thể) được dành cho sử dụng theo chương trình, vì vậy tôi không thấy vấn đề gì với điều này. Người dùng API có thể tự do đóng gói các tham số trong một đối tượng bên trong mã của riêng họ.

  • Về mặt kỹ thuật, bạn cũng có thể đặt một đối tượng vào một tham số URL (dưới dạng JSON, XML hoặc bất cứ thứ gì), nhưng điều đó là bất thường, vì vậy tôi sẽ tránh nó nếu có thể.

1) Nói đúng ra, bạn có thể sử dụng một cơ thể với một GETyêu cầu, nhưng điều này là bất thường và thường không được khuyến khích; xem ví dụ HTTP GET với thân yêu cầu .


Cuối cùng, giống như các phương thức trong mã nguồn có danh sách tham số dài, bạn có thể muốn xem xét liệu API REST có cần cấu trúc lại hay không. Giống như trong mã nguồn, danh sách tham số dài như vậy biểu thị điểm cuối API đang thực hiện nhiều việc khác nhau. Liệu nó có thể có ý nghĩa để chia nó ra, hoặc cung cấp các thiết lập mặc định? Nhưng đó là một câu hỏi khác ...


Về mặt kỹ thuật, bạn cũng có thể gửi một cơ thể với một GET mặc dù không bình thường
Ewan

Ngoài ra, bạn có chắc bạn có nghĩa là idempotent không, tôi sẽ nói 'GetTodaysDayName () có thể được coi là idempotent, nhưng bạn sẽ không muốn lưu trữ nó
Ewan

Hãy để trận chiến GET vs POST bắt đầu !!!! :)
Ewan

@Ewan: Đối với bộ đệm ẩn GetTodaysDayName: Giả sử bạn cần tên ngày hôm nay mười lần một giây và không quan tâm đến việc sử dụng sai ngày trong vài giây, rất có thể bạn muốn lưu trữ bộ đệm đó. Tuy nhiên, tôi đã sử dụng sai "idempotent", những gì tôi có trong tâm trí là "an toàn" (= không sửa đổi). Đã chỉnh sửa.
sleske

1
@Ewan những trận chiến mang tính xây dựng trong đó các "đối thủ" làm phong phú thêm phản ứng của nhau được chào đón nhiều hơn. Cảm ơn cả hai bạn đã có một cái nhìn tổng quan rất toàn diện về tất cả các tùy chọn!
Christophe

3

Thực hành tốt nhất là POST các tham số như là một đối tượng.

Điều này tránh giới hạn độ dài URL và các vấn đề khác với chuỗi truy vấn. Nếu bạn gửi nhiều tham số trong JSON thì một đối tượng là cách thực hiện tiêu chuẩn, do đó, việc giải tuần tự hóa thành một ý nghĩa.

Bạn có thể tránh tạo các đối tượng 'Yêu cầu' ngẫu nhiên chỉ được sử dụng trong Bộ điều khiển của mình bằng cách khử lưu trữ thành đối tượng động nếu bạn muốn; mặc dù đúc đúng loại sau đó có thể lộn xộn như nhau.

Trong những ngày xưa, bạn sẽ có thể có nhiều tham số trong hành động điều khiển của bạn tự động được liên kết với các trường của đối tượng JSON đến. Nhưng điều này không còn hoạt động ngoài hộp trong lõi .net.

Mặc dù có cái này, cái mà tôi có thể muốn thử

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/application-model?view=aspnetcore-2.1#application-model-usage-in-webapicompatshim

Chỉnh sửa: Chỉ cần thêm một vài điểm về việc sử dụng GET

  • Bộ nhớ đệm: GET sẽ được lưu trữ bởi các máy khách tuân theo thông số HTTP. Nhưng thông số kỹ thuật được thiết kế để làm cho các trang web tải nhanh hơn. Bộ nhớ đệm rất hữu ích nếu kết quả API của bạn có cùng yêu cầu bộ đệm như trang web, nhưng không hữu ích nếu không có. Bạn có thể thêm bộ nhớ đệm phản hồi POST của riêng bạn trong máy khách nếu được yêu cầu.

  • Độ dài URL: Đây chủ yếu là một vấn đề khi bạn đang gửi một mảng. Rõ ràng một mảng có thể dễ dàng nhận được rất lâu và các tên tham số chuỗi truy vấn sẽ được lặp lại cho mỗi mục. Tuy nhiên, ngay cả khi bạn chỉ gửi một chuỗi, về mặt kỹ thuật, chuỗi đó có thể rất dài.

  • Ghi nhật ký: Theo mặc định, nhiều máy chủ web sẽ ghi nhật ký toàn bộ chuỗi truy vấn. Thường thì bạn không muốn dữ liệu tham số kết thúc trong nhật ký văn bản thuần túy.

  • NHẬN với cơ thể: Đây dường như là câu trả lời hoàn hảo, thỏa mãn những người theo chủ nghĩa REST trong khi cho phép một cấu trúc dữ liệu tốt, nhưng thật bất thường và nhăn mặt, POST là cách tiêu chuẩn để gửi một cơ thể.


2
Tôi không nghĩ rằng đây là thỏa thuận - thực hành tốt nhất. Đặc biệt, nếu yêu cầu là idempotent, nó thực hành tốt nhất để sử dụng GETvà không PUT(đối với năng bộ nhớ cache, trong số những thứ khác). Và giới hạn độ dài URL hiện nay khá lớn, do đó không nhất thiết phải là vấn đề.
sleske

@sleske Nếu bạn nghĩ GET tốt hơn, bạn nên viết câu trả lời về lý do tại sao. Chuỗi z có thể dài 4Mb
Ewan

thực sự chỉ là googling và độ dài chuỗi json tối đa có vẻ không chắc chắn
Ewan

Với bối cảnh, không cần phải có các tham số yêu cầu không có trong nhật ký của bạn - trừ khi bạn không muốn phân tích về những gì mọi người tìm kiếm trên trang của bạn;) GEThoàn toàn có ý nghĩa từ hai quan điểm: a) phân tích và b) a người dùng có thể lưu trữ truy vấn để sau này hoặc chia sẻ truy vấn.
Thomas Junk

@ThomasJunk bạn đề cập đến bối cảnh nào? chuỗi được gọi là 'z', có thể có bất cứ thứ gì trong đó. GDPR phạt 20 triệu đô la là bao nhiêu?
Ewan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.