9

Khi chúng tôi thiết kế API, mục tiêu là cung cấp cho người dùng một số quyền lực đối với dịch vụ mà chúng tôi cung cấp. Mặc dù các động từ HTTP và URL tài nguyên cho phép thực hiện một số tương tác cơ bản, nhưng đôi khi cần phải cung cấp chức năng bổ sung, nếu không hệ thống trở nên quá cồng kềnh để làm việc.

Một ví dụ về điều này là phân trang: chúng tôi không thể gửi mọi bài báo cho khách hàng trong một phản hồi nếu chúng tôi có hàng triệu bài báo trong cơ sở dữ liệu của mình.

Một cách để hoàn thành việc này là sử dụng tham số hóa .

Tham số hóa là gì?

Nói chung, tham số hóa là một loại cấu hình yêu cầu.

Trong ngôn ngữ lập trình, chúng ta có thể yêu cầu một giá trị trả về từ một hàm. Nếu hàm không nhận bất kỳ tham số nào, chúng tôi không thể ảnh hưởng trực tiếp đến giá trị trả về này.

Điều tương tự cũng xảy ra đối với các API, đặc biệt là các API không trạng thái như API REST. Roy Fielding đã nói điều này một cách hùng hồn:

Tất cả các tương tác REST đều không có trạng thái. Nghĩa là, mỗi yêu cầu chứa tất cả thông tin cần thiết để trình kết nối hiểu được yêu cầu, độc lập với bất kỳ yêu cầu nào có trước nó.

Có nhiều cách trong HTTP để thêm các tham số vào yêu cầu của chúng tôi: chuỗi truy vấn, nội dung của các yêu cầu POST, PUT và PATCH và tiêu đề. Mỗi loại có các trường hợp sử dụng và quy tắc riêng.

Cách đơn giản nhất để thêm tất cả dữ liệu tham số là đưa mọi thứ vào phần thân. Nhiều API hoạt động theo cách này. Mọi điểm cuối đều sử dụng POST và tất cả các tham số đều nằm trong phần thân. Điều này đặc biệt đúng trong các API kế thừa đã tích lũy ngày càng nhiều tham số hơn một thập kỷ hoặc lâu hơn, đến nỗi chúng không còn phù hợp với chuỗi truy vấn.

Mặc dù trường hợp này thường xuyên xảy ra hơn là không, nhưng tôi muốn coi nó là một trường hợp cạnh trong thiết kế API. Nếu chúng ta đặt câu hỏi phù hợp từ trước, chúng ta có thể ngăn chặn kết quả như vậy.

Chúng ta muốn thêm loại thông số nào?

Câu hỏi đầu tiên chúng ta nên tự hỏi là loại tham số chúng ta muốn thêm vào?

Có thể đó là một tham số là trường tiêu đề đã được chuẩn hóa trong đặc tả HTTP .

Có nhiều trường được tiêu chuẩn hóa. Đôi khi chúng ta có thể phát minh lại bánh xe và thêm thông tin vào một nơi khác. Tôi không nói rằng chúng ta không thể làm khác đi. GraphQL, ví dụ, đã làm những gì tôi cho là điên rồ từ góc độ REST, nhưng nó vẫn hoạt động. Đôi khi nó chỉ đơn giản hơn để sử dụng những gì đã có.

Lấy ví dụ Accepttiêu đề. Điều này cho phép chúng tôi xác định định dạng hoặc loại phương tiện , phản hồi cần thực hiện. Chúng tôi có thể sử dụng điều này để cho API biết rằng chúng tôi cần JSONhoặc XML. Chúng tôi cũng có thể sử dụng điều này để lấy phiên bản của API .

Cũng có một Cache-Controltiêu đề mà chúng tôi có thể sử dụng để ngăn không cho API gửi cho chúng tôi một phản hồi đã lưu trong bộ nhớ cache no-cache, thay vì sử dụng một chuỗi truy vấn dưới dạng cache buster ( ?cb=)

Ủy quyền cũng có thể được coi là một tham số. Tùy thuộc vào chi tiết ủy quyền của API, các phản hồi khác nhau có thể là do được ủy quyền hoặc không được ủy quyền. HTTP xác định mộtAuthorization tiêu đề cho mục đích này.

Sau khi chúng tôi kiểm tra tất cả các trường tiêu đề mặc định, bước tiếp theo là đánh giá xem chúng tôi nên tạo trường tiêu đề tùy chỉnh cho thông số của mình hay đặt nó vào chuỗi truy vấn của URL của chúng tôi.

Khi nào chúng ta nên sử dụng chuỗi truy vấn?

Nếu chúng tôi biết các tham số chúng tôi muốn thêm không thuộc trường tiêu đề mặc định và không nhạy cảm, chúng tôi nên xem liệu chuỗi truy vấn có phải là nơi thích hợp cho chúng hay không.

Trước đây, việc sử dụng chuỗi truy vấn, như tên của nó, là để truy vấn dữ liệu. Có một phần tử HTML có thể được sử dụng để gửi một số từ khóa đến máy chủ và máy chủ sẽ phản hồi bằng danh sách các trang phù hợp với từ khóa.

Sau đó, chuỗi truy vấn được định vị lại cho các biểu mẫu web để gửi dữ liệu đến máy chủ thông qua yêu cầu GET.

Do đó, trường hợp sử dụng chính của chuỗi truy vấn là lọc và cụ thể là hai trường hợp lọc đặc biệt: tìm kiếm và phân trang. Tôi sẽ không đi vào chi tiết ở đây, bởi vì chúng tôi đã giải quyết chúng trong bài viết này .

Nhưng khi định vị lại cho các biểu mẫu web, nó cũng có thể được sử dụng cho các loại thông số khác nhau. API RESTful có thể sử dụng yêu cầu POST hoặc PUT với một phần thân để gửi dữ liệu biểu mẫu đến máy chủ.

Một ví dụ sẽ là một tham số cho các biểu diễn lồng nhau. Theo mặc định, chúng tôi trả về một đại diện đơn giản của một bài báo. Khi một ?withCommentschuỗi truy vấn được thêm vào điểm cuối, chúng tôi trả về các nhận xét của bài viết đó trong dòng, vì vậy chỉ cần một yêu cầu.

Thông số như vậy có đi vào tiêu đề tùy chỉnh hay chuỗi truy vấn chủ yếu là câu hỏi về kinh nghiệm của nhà phát triển.

Đặc tả HTTP tuyên bố rằng các trường tiêu đề là loại giống như các tham số hàm, vì vậy chúng thực sự được coi là các tham số mà chúng ta muốn sử dụng. Tuy nhiên, việc thêm chuỗi truy vấn vào URL được thực hiện nhanh chóng và rõ ràng hơn là tạo tiêu đề khách hàng trong trường hợp này.

Các trường này hoạt động như các công cụ sửa đổi yêu cầu, với ngữ nghĩa tương đương với các tham số trên lệnh gọi phương thức ngôn ngữ lập trình.

Các tham số giữ nguyên trên tất cả các điểm cuối sẽ phù hợp hơn cho các tiêu đề. Ví dụ: mã thông báo xác thực được gửi theo mọi yêu cầu.

Các tham số có tính năng động cao, đặc biệt là khi chúng chỉ hợp lệ cho một vài điểm cuối, nên đi trong chuỗi truy vấn. Ví dụ: các tham số bộ lọc khác nhau đối với mọi điểm cuối.

Phần thưởng: Tham số mảng và bản đồ

Một câu hỏi thường xuất hiện là phải làm gì với các tham số mảng bên trong chuỗi truy vấn?

Ví dụ, nếu chúng ta có nhiều tên mà chúng ta muốn tìm kiếm.

Một giải pháp là sử dụng dấu ngoặc vuông:

/authors?name[]=kay&name[]=xing


Nhưng đặc điểm kỹ thuật HTTP cho biết:

Máy chủ được xác định bằng địa chỉ theo nghĩa Giao thức Internet, phiên bản 6 [RFC3513] trở lên, được phân biệt bằng cách đặt ký tự IP trong dấu ngoặc vuông (“[” và “]”). Đây là nơi duy nhất cho phép các ký tự dấu ngoặc vuông trong cú pháp URI.

Nhiều triển khai của máy chủ và máy khách HTTP không quan tâm đến thực tế này, nhưng cần lưu ý điều này.

Một giải pháp khác được cung cấp chỉ đơn giản là sử dụng một tên tham số nhiều lần:

/authors?name=kay&name=xing


Đây là một giải pháp hợp lệ nhưng có thể làm giảm trải nghiệm của nhà phát triển. Thông thường, khách hàng chỉ sử dụng cấu trúc dữ liệu giống như bản đồ, trải qua quá trình chuyển đổi chuỗi đơn giản trước khi được thêm vào URL, có khả năng dẫn đến ghi đè các giá trị sau. Một chuyển đổi phức tạp hơn là cần thiết trước khi yêu cầu có thể được gửi đi.

Một cách khác là tách các giá trị bằng các ,ký tự, được phép không được mã hóa bên trong URL.

/authors?name=kay,xing


Đối với cấu trúc dữ liệu giống như bản đồ, chúng ta có thể sử dụng .ký tự, ký tự này cũng được phép không được mã hóa.

/articles?age.gt=21&age.lt=40


Cũng có thể mã hóa URL toàn bộ chuỗi truy vấn để nó có thể sử dụng bất kỳ ký tự hoặc định dạng nào mà chúng ta muốn. Cần lưu ý rằng điều này cũng có thể làm giảm kinh nghiệm của nhà phát triển đi một chút.

Khi nào thì chúng ta không nên sử dụng chuỗi truy vấn?

Chuỗi truy vấn là một phần của URL của chúng tôi và URL của chúng tôi có thể được đọc bởi mọi người ngồi giữa các máy khách và API, vì vậy chúng tôi không nên đặt dữ liệu nhạy cảm như mật khẩu vào chuỗi truy vấn.

Ngoài ra, trải nghiệm của nhà phát triển sẽ bị ảnh hưởng rất nhiều nếu chúng tôi không coi trọng thiết kế và độ dài URL. Chắc chắn, hầu hết các ứng dụng HTTP sẽ cho phép độ dài ký tự là năm con số trong một URL, nhưng việc gỡ lỗi các loại chuỗi như vậy không phải là điều dễ chịu.

Vì mọi thứ đều có thể được định nghĩa là tài nguyên, nên đôi khi sử dụng điểm cuối POST để sử dụng tham số nặng có thể có ý nghĩa hơn. Điều này cho phép chúng tôi gửi tất cả dữ liệu trong phần thân tới API.

Thay vì gửi một yêu cầu GET tới một tài nguyên có nhiều tham số trong chuỗi truy vấn, điều đó có thể dẫn đến một URL thực sự dài không thể gỡ lỗi, chúng tôi có thể thiết kế nó như một tài nguyên (ví dụ: tài nguyên tìm kiếm). Tùy thuộc vào những thứ mà API của chúng tôi cần làm để đáp ứng yêu cầu của chúng tôi, chúng tôi thậm chí có thể sử dụng điều này để lưu vào bộ nhớ cache các kết quả tính toán của mình.

Chúng tôi sẽ ĐĂNG một yêu cầu mới tới /searchesđiểm cuối của chúng tôi , yêu cầu này chứa cấu hình / thông số tìm kiếm của chúng tôi trong nội dung. ID tìm kiếm được trả về, chúng tôi có thể sử dụng sau này để NHẬN kết quả tìm kiếm của chúng tôi.

Phần kết luận

Như với tất cả các phương pháp hay nhất, công việc của chúng tôi với tư cách là nhà thiết kế và kiến ​​trúc sư API không phải tuân theo một cách tiếp cận là “giải pháp tốt nhất” mà là tìm hiểu cách sử dụng các API của chúng tôi.

Các trường hợp sử dụng thường xuyên nhất phải là trường hợp đơn giản nhất để hoàn thành và người dùng sẽ thực sự khó thực hiện sai.

Do đó, điều quan trọng là phải phân tích các mẫu sử dụng API của chúng tôi ngay từ đầu - chúng tôi có dữ liệu càng sớm, thì việc thực hiện các thay đổi càng dễ dàng nếu chúng tôi làm sai thiết kế của mình. Dịch vụ phân tích của Moesif có thể giúp bạn điều đó.

Nếu chúng ta đi theo một con đường vì nó đơn giản hơn để nắm bắt hoặc dễ thực hiện hơn, chúng ta phải nhìn vào những gì chúng ta đạt được từ nó.

Vì các tài nguyên lồng nhau có thể được sử dụng để làm cho các URL dễ đọc hơn, chúng cũng có thể trở nên quá dài và không thể đọc được nếu chúng ta lồng quá nhiều. Đối với các thông số cũng vậy. Nếu chúng ta thấy mình đang tạo một điểm cuối có một chuỗi truy vấn lớn, có thể tốt hơn là trích xuất một tài nguyên khác từ nó và gửi các tham số bên trong phần thân.

|