Bạn đã xây dựng một API hiện đại. Phương thức GET dùng để lấy dữ liệu, POST để tạo tài nguyên mới—cho đến nay mọi thứ đều suôn sẻ. Nhưng khi cập nhật dữ liệu, mọi thứ trở nên phức tạp.
Giả sử người dùng chỉ muốn thay đổi email của họ. Bạn có thực sự cần họ gửi lại toàn bộ hồ sơ người dùng không? Điều đó thật cồng kềnh, kém hiệu quả và dễ gây lỗi—đặc biệt với kết nối chậm hoặc các bản cập nhật xung đột.
Có một cách tốt hơn: JSON Patch.
Thay vì gửi toàn bộ đối tượng, bạn chỉ gửi các thay đổi. Hãy nghĩ về nó giống như việc đưa cho một thợ may danh sách các chỉnh sửa thay vì may lại toàn bộ bộ đồ.
Vì JSON đã trở thành ngôn ngữ phổ quát cho các API, JSON Patch mang đến một giải pháp nhẹ nhàng, tinh tế cho các bản cập nhật một phần.
Tất nhiên, việc thiết kế và kiểm thử API với JSON Patch đòi hỏi các công cụ phù hợp. Đó là lúc Apidog phát huy tác dụng. Nó cho phép bạn tạo, kiểm thử và xác thực các yêu cầu JSON Patch một cách dễ dàng—để bạn biết các bản cập nhật của mình hoạt động như mong muốn trước khi viết một dòng mã nào. Hơn hết, nó miễn phí để tải xuống và bắt đầu thử nghiệm ngay hôm nay.
Bạn muốn một nền tảng tích hợp, tất cả trong một để Đội ngũ Phát triển của bạn làm việc cùng nhau với năng suất tối đa?
Apidog đáp ứng mọi yêu cầu của bạn và thay thế Postman với mức giá phải chăng hơn nhiều!
Tiếp theo, hãy cùng tìm hiểu JSON Patch là gì, cách nó hoạt động và tại sao nó nên là một phần trong dự án tiếp theo của bạn.
Vấn đề: Yêu cầu PUT "Mù quáng"

Để hiểu tại sao JSON Patch lại hữu ích như vậy, trước tiên chúng ta cần hiểu vấn đề mà nó giải quyết. Theo truyền thống, việc cập nhật một tài nguyên trong API RESTful được thực hiện bằng phương thức HTTP PUT
.
Một yêu cầu PUT
được thiết kế để có tính bất biến (thực hiện cùng một yêu cầu nhiều lần có cùng hiệu quả như thực hiện một lần) và nó thường thay thế toàn bộ tài nguyên tại URL đích bằng biểu diễn mới được cung cấp trong phần thân yêu cầu.
Hãy tưởng tượng một tài nguyên hồ sơ người dùng:
GET /users/123
{
"id": 123,
"username": "johndoe",
"email": "john.old@example.com",
"firstName": "John",
"lastName": "Doe",
"age": 30,
"accountStatus": "active",
"preferences": {
"theme": "light",
"notifications": true
},
"signUpDate": "2023-01-15"
}
Bây giờ, nếu John chỉ muốn thay đổi địa chỉ email của mình, một yêu cầu PUT
điển hình sẽ trông như thế này:
PUT /users/123
{
"id": 123,
"username": "johndoe",
"email": "john.new@example.com", // Trường đã thay đổi
"firstName": "John",
"lastName": "Doe",
"age": 30,
"accountStatus": "active",
"preferences": {
"theme": "light",
"notifications": true
},
"signUpDate": "2023-01-15"
}
Bạn có thấy vấn đề không? Chúng ta phải gửi lại mọi trường, mặc dù 99% dữ liệu không thay đổi. Cách tiếp cận này có một số nhược điểm:
- Tăng băng thông: Chúng ta đang gửi rất nhiều dữ liệu không cần thiết qua mạng. Đối với các tài nguyên lớn, điều này có thể gây ảnh hưởng đáng kể đến hiệu suất, đặc biệt trên mạng di động.
- Nguy cơ xung đột cao hơn: Nếu một tiến trình khác cập nhật trường
age
trong khi John đang chỉnh sửaemail
của mình, yêu cầuPUT
của John có thể vô tình ghi đè giá trị tuổi mới đó bằng giá trị cũ mà anh ta đã gửi. - Phức tạp cho phía máy khách: Ứng dụng máy khách trước tiên phải
GET
toàn bộ tài nguyên, sửa đổi trường cụ thể, sau đóPUT
toàn bộ trở lại. Đó là nhiều bước và yêu cầu máy khách phải quản lý toàn bộ trạng thái.
Đây là lúc phương thức HTTP PATCH
xuất hiện để giải cứu.
Giải pháp: Giới thiệu HTTP PATCH và JSON Patch
Phương thức HTTP PATCH
được giới thiệu để cho phép sửa đổi một phần tài nguyên. Không giống như PUT
, vốn thay thế toàn bộ tài nguyên, PATCH
áp dụng một tập hợp các thay đổi cho tài nguyên.
Nhưng có một vấn đề: tiêu chuẩn HTTP không định nghĩa định dạng của những "thay đổi" đó phải là gì. Bạn có thể tự mình tạo ra. Bạn có thể gửi một cái gì đó như:
{ "op": "change_email", "value": "new@example.com" }
Nhưng điều này sẽ là tùy chỉnh, không theo tiêu chuẩn và các nhà phát triển khác sẽ phải học ngôn ngữ cụ thể của bạn.
Đây là khoảng trống mà JSON Patch lấp đầy. JSON Patch (được định nghĩa trong RFC 6902) là một định dạng tiêu chuẩn để chỉ định các thay đổi được áp dụng cho một tài liệu JSON. Nó cung cấp một ngôn ngữ rõ ràng, không mơ hồ để mô tả chính xác cách một tài liệu JSON nên được sửa đổi.
Khi bạn kết hợp phương thức HTTP PATCH
với một phần thân được định dạng dưới dạng tài liệu JSON Patch, bạn có một cách mạnh mẽ, dựa trên tiêu chuẩn để thực hiện các bản cập nhật một phần.
JSON Patch Hoạt động như thế nào: Những điều cơ bản
Một tài liệu JSON Patch luôn là một mảng JSON. Mỗi phần tử trong mảng là một đối tượng thao tác. Các thao tác này được áp dụng cho tài liệu đích theo thứ tự, và toàn bộ bản vá là nguyên tử, nghĩa là nếu bất kỳ thao tác nào thất bại, toàn bộ bản vá sẽ bị hủy bỏ, và tài liệu vẫn không thay đổi.
Mỗi đối tượng thao tác có một thành phần op
bắt buộc (viết tắt của "operation") để chỉ định hành động cần thực hiện. Các thao tác phổ biến nhất là add
, remove
, replace
, move
và copy
.
Hãy xem ví dụ trước về việc John thay đổi email của mình. Sử dụng JSON Patch, yêu cầu trở nên đơn giản hơn đáng kể:
PATCH /users/123
[
{ "op": "replace", "path": "/email", "value": "john.new@example.com" }
]
Chỉ vậy thôi! Chúng ta đang gửi một thao tác duy nhất: "thay thế giá trị tại đường dẫn '/email' bằng giá trị mới này." Yêu cầu nhỏ gọn, rõ ràng và hướng đến mục đích. Chúng ta không chạm vào bất kỳ trường nào khác.
Hiểu về thuộc tính path
Thuộc tính path
là một JSON Pointer (RFC 6901), một chuỗi sử dụng cú pháp dựa trên dấu gạch chéo để điều hướng qua tài liệu JSON đến giá trị cụ thể mà bạn muốn thao tác.
"/email"
trỏ đến trườngemail
cấp gốc."/preferences/theme"
trỏ đến trườngtheme
bên trong đối tượngpreferences
."/firstName"
trỏ đến trườngfirstName
.
Cú pháp này rất mạnh mẽ để điều hướng các cấu trúc JSON lồng nhau.
JSON Patch so với JSON Merge Patch
Các nhà phát triển thường nhầm lẫn JSON Patch (RFC 6902) với JSON Merge Patch (RFC 7386). Hãy làm rõ.
JSON Patch:
- Mô tả một chuỗi các thao tác.
- Rất chính xác và cho phép cập nhật phức tạp.
- Ví dụ: thay thế, di chuyển, sao chép.
JSON Merge Patch:
- Gửi một tài liệu JSON một phần để hợp nhất vào tài liệu gốc.
- Đơn giản hơn, nhưng ít linh hoạt hơn.
- Ví dụ:
{ "name": "Bob" }
sẽ thay thế trường tên.
Tóm lại:
- Sử dụng JSON Merge Patch cho các bản cập nhật đơn giản, nông.
- Sử dụng JSON Patch cho các thao tác phức tạp hoặc nhiều thao tác.
Các thao tác của JSON Patch
Hãy cùng phân tích các thao tác phổ biến nhất với các ví dụ. Chúng ta sẽ sử dụng cùng một hồ sơ người dùng làm tài liệu đích.
1. Thao tác add
Thao tác add
được sử dụng để chèn một giá trị mới vào một đối tượng hoặc mảng.
Thêm một thuộc tính mới vào một đối tượng:
{ "op": "add", "path": "/twitterHandle", "value": "@johndoe" }
Điều này thêm một trường twitterHandle
mới vào đối tượng người dùng.
Thêm một phần tử vào một mảng (tại một chỉ mục cụ thể):
Hãy tưởng tượng người dùng có một mảng "hobbies"
: ["reading", "cycling"]
.
{ "op": "add", "path": "/hobbies/1", "value": "hiking" }
Điều này chèn "hiking" vào chỉ mục 1, tạo ra ["reading", "hiking", "cycling"]
. Để thêm vào cuối mảng, bạn có thể sử dụng /-
: { "op": "add", "path": "/hobbies/-", "value": "hiking" }
.
2. Thao tác remove
Thao tác remove
xóa một giá trị tại một vị trí được chỉ định.
Xóa một thuộc tính khỏi một đối tượng:
{ "op": "remove", "path": "/age" }
Điều này xóa toàn bộ trường age
khỏi đối tượng người dùng.
Xóa một phần tử khỏi một mảng:
{ "op": "remove", "path": "/hobbies/0" }
Điều này xóa phần tử đầu tiên (chỉ mục 0) khỏi mảng hobbies
.
3. Thao tác replace
Thao tác replace
về cơ bản là sự kết hợp của remove
và add
tại cùng một đường dẫn. Nó thay thế giá trị hiện có tại một vị trí bằng một giá trị mới. Ví dụ email của chúng ta là một trường hợp replace
kinh điển.
Thay đổi tùy chọn chủ đề của người dùng:
{ "op": "replace", "path": "/preferences/theme", "value": "dark" }
4. Thao tác move
Thao tác move
xóa một giá trị từ một vị trí và thêm nó vào một vị trí khác.
Di chuyển một giá trị từ thuộc tính này sang thuộc tính khác:
{ "op": "move", "from": "/firstName", "path": "/first_name" }
Điều này sẽ di chuyển giá trị của firstName
sang một thuộc tính mới có tên là first_name
và xóa thuộc tính firstName
cũ.
5. Thao tác copy
Thao tác copy
sao chép một giá trị từ một vị trí này sang một vị trí khác. Giá trị gốc vẫn không thay đổi.
Tạo bản sao lưu của một cài đặt:
{ "op": "copy", "from": "/preferences/theme", "path": "/backupTheme" }
Điều này sao chép giá trị chủ đề hiện tại sang một trường backupTheme
mới.
6. Thao tác test
Đây là một tính năng an toàn. Thao tác test
kiểm tra xem một giá trị tại một vị trí có bằng một giá trị được chỉ định hay không. Nếu kiểm tra thất bại, toàn bộ bản vá sẽ bị hủy bỏ. Điều này cực kỳ hữu ích để ngăn ngừa xung đột (khóa lạc quan).
Đảm bảo không ai khác đã thay đổi email trước khi cập nhật:
[
{ "op": "test", "path": "/email", "value": "john.old@example.com" },
{ "op": "replace", "path": "/email", "value": "john.new@example.com" }
]
Nếu email
hiện tại không phải là "john.old@example.com"
(có thể một tiến trình khác đã thay đổi nó), thao tác test
sẽ thất bại, và thao tác replace
sẽ không bao giờ xảy ra. Điều này đảm bảo bản cập nhật của bạn dựa trên trạng thái được biết gần nhất.
Tại sao nên sử dụng JSON Patch? Lợi ích
- Hiệu quả: Lợi ích rõ ràng nhất. Bạn chỉ gửi các thay đổi, giảm đáng kể kích thước tải trọng và cải thiện hiệu suất.
- Kiểm soát đồng thời: Thao tác
test
cung cấp một cơ chế tích hợp để khóa lạc quan, giúp bạn tránh mất các bản cập nhật và tình trạng tranh chấp. - Tính nguyên tử: Bản chất "tất cả hoặc không gì cả" của việc áp dụng bản vá đảm bảo dữ liệu của bạn luôn nhất quán. Nếu thao tác thứ năm trong một bản vá mười thao tác thất bại, bốn thao tác đầu tiên sẽ được hoàn tác.
- Rõ ràng và có mục đích: Phần thân yêu cầu mô tả rõ ràng mục đích của thay đổi ("thay thế email", "thêm một sở thích") thay vì chỉ đơn thuần là gửi một trạng thái mới. Điều này giúp nhật ký dễ đọc hơn và gỡ lỗi dễ dàng hơn.
- Tiêu chuẩn hóa: Đây là một tiêu chuẩn IETF (RFC 6902). Các nhà phát triển khác sẽ nhận ra nó, và nhiều thư viện, framework trên các ngôn ngữ lập trình khác nhau đã có hỗ trợ tích hợp để phân tích cú pháp và áp dụng các tài liệu JSON Patch.
Những lỗi thường gặp và sai lầm với JSON Patch
Mặc dù JSON Patch mạnh mẽ, các nhà phát triển thường gặp phải những vấn đề này:
- Sử dụng sai đường dẫn (lỗi cú pháp JSON Pointer).
- Quên các trường bắt buộc như
value
hoặcfrom
. - Áp dụng bản vá cho các đường dẫn không tồn tại.
- Lạm dụng các thao tác
test
một cách không chính xác. - Nhầm lẫn JSON Patch với JSON Merge Patch.
Tại sao các API sử dụng JSON Patch
Các API yêu thích JSON Patch vì nó:
- Hiệu quả: Chỉ gửi những gì đã thay đổi.
- Nguyên tử: Nhiều thay đổi trong một yêu cầu.
- Linh hoạt: Hỗ trợ các thao tác nâng cao như di chuyển/sao chép.
- Tiêu chuẩn hóa: Hoạt động trên các hệ thống khác nhau.
Ví dụ, API của GitHub hỗ trợ JSON Patch để chỉnh sửa siêu dữ liệu kho lưu trữ một cách hiệu quả.
JSON Patch trong API REST
Trong các API RESTful, JSON Patch thường được sử dụng với phương thức HTTP PATCH.
PATCH so với PUT:
- PUT thay thế toàn bộ tài nguyên.
- PATCH cập nhật một phần của tài nguyên.
Với JSON Patch, Content-Type
là:
application/json-patch+json
Điều này cho máy chủ biết rằng phần thân chứa một tài liệu JSON Patch.
JSON Patch trong GraphQL và các giao thức khác
Mặc dù JSON Patch chủ yếu được sử dụng trong các API REST, nó cũng có liên quan trong:
- GraphQL mutations: Áp dụng các bản cập nhật tăng dần.
- gRPC với tải trọng JSON: Gửi các bản vá có cấu trúc.
- Kiến trúc hướng sự kiện: Chỉ phát sóng các thay đổi thay vì toàn bộ đối tượng.
JSON Patch cải thiện hiệu quả như thế nào
Hãy tưởng tượng một ứng dụng di động đồng bộ hóa hồ sơ người dùng. Thay vì tải lại một tệp JSON 2MB cho mỗi bản cập nhật nhỏ, ứng dụng có thể chỉ gửi một yêu cầu bản vá nhỏ.
Điều này có nghĩa là:
- Thời gian đồng bộ hóa nhanh hơn.
- Sử dụng dữ liệu di động ít hơn.
- Hiệu suất máy chủ tốt hơn.
Thách thức và cân nhắc
JSON Patch mạnh mẽ, nhưng không phải không có sự phức tạp.
- Triển khai phức tạp trên máy chủ: Áp dụng một bản vá chính xác trên máy chủ phức tạp hơn nhiều so với việc chỉ chấp nhận một đối tượng JSON mới. Bạn cần xác thực từng thao tác, xử lý các con trỏ đến các đường dẫn không tồn tại một cách thích hợp và đảm bảo toàn bộ chuỗi được áp dụng một cách nguyên tử. May mắn thay, hầu hết các framework web hiện đại đều có thư viện để xử lý điều này cho bạn (ví dụ:
json-patch
cho Node.js,jsonpatch
cho Python,JsonPatchDocument
trong .NET). - Tiềm ẩn lỗi: Một tài liệu bản vá bị định dạng sai hoặc một con trỏ không hợp lệ (ví dụ: cố gắng
replace
một trường không tồn tại) sẽ dẫn đến lỗi. API của bạn phải xử lý những lỗi này một cách duyên dáng và trả về các thông báo lỗi rõ ràng (thường là422 Unprocessable Entity
hoặc400 Bad Request
). - Không phải là viên đạn bạc: Đối với các tài nguyên rất đơn giản, một
PUT
vẫn có thể đơn giản hơn. JSON Patch tỏa sáng khi tài nguyên của bạn lớn hoặc khi bạn cần hỗ trợ các bản cập nhật phức tạp, có điều kiện.
Kiểm thử Endpoint JSON Patch với Apidog

Kiểm thử JSON Patch thủ công có thể gây khó chịu. Đây là lúc một công cụ API tinh vi trở nên vô giá. Apidog, một nền tảng phát triển API tất cả trong một, có thể là một cứu cánh tuyệt vời ở đây:
- Kiểm thử: Bạn có thể dễ dàng kiểm thử endpoint PATCH trong một bảng điều khiển trực quan và nhận được kết quả xác thực phản hồi.
- Tài liệu: Bạn có thể tạo tài liệu cho các endpoint PATCH của mình trong Apidog, hiển thị rõ ràng cho các thành viên khác trong nhóm định dạng mong đợi, giúp cải thiện sự cộng tác và giảm lỗi tích hợp.
Quy trình làm việc ví dụ trong Apidog:
- Tạo một yêu cầu mới.
- Đặt phương thức thành PATCH.
- Thêm
Content-Type: application/json-patch+json
. - Nhập mảng JSON Patch của bạn.
- Gửi và xác minh kết quả ngay lập tức.
Bằng cách sử dụng Apidog, bạn chuyển từ việc đoán xem bản vá của mình có đúng không sang việc biết rằng nó được xây dựng đúng cách, cho phép bạn tự tin triển khai và sử dụng các API JSON Patch và bắt đầu kiểm thử JSON Patch như một chuyên gia.
Các phương pháp hay nhất của JSON Patch
Để sử dụng JSON Patch hiệu quả:
- Xác thực các tài liệu JSON Patch của bạn trước khi gửi.
- Sử dụng các thao tác kiểm tra khi tính nhất quán là quan trọng.
- Giữ các bản vá nhỏ để đạt hiệu quả.
- Tài liệu hóa API của bạn rõ ràng khi sử dụng JSON Patch.
- Sử dụng các công cụ như Apidog để hợp lý hóa việc kiểm thử.
Kết luận: Nắm bắt một tiêu chuẩn API hiệu quả hơn
Vậy, JSON Patch là gì?
Đó là một cách tiêu chuẩn hóa để mô tả các thay đổi đối với tài liệu JSON bằng cách sử dụng các thao tác như thêm, xóa và thay thế. Thay vì gửi toàn bộ đối tượng, bạn có thể chỉ gửi các thay đổi, làm cho API của bạn trở nên hiệu quả, đáng tin cậy và linh hoạt hơn.
JSON Patch biến đổi cách chúng ta suy nghĩ về việc cập nhật dữ liệu qua API. Nó đưa chúng ta từ công cụ thô sơ là thay thế toàn bộ tài liệu sang sự chính xác của các thay đổi tinh vi. Bằng cách nắm bắt tiêu chuẩn này, chúng ta xây dựng các API hiệu quả hơn, ít bị xung đột hơn và rõ ràng hơn về mục đích của chúng.
Mặc dù nó đòi hỏi một chút suy nghĩ ban đầu hơn về phía máy chủ, nhưng lợi ích cho các ứng dụng khách và hiệu suất mạng là đáng kể. Lần tới khi bạn thấy mình thiết kế một endpoint cập nhật, hãy chống lại PUT
mặc định và tự hỏi: "Liệu đây có phải là một công việc cho PATCH
không?"
Đối với các nhà phát triển, việc hiểu JSON Patch là chìa khóa để làm việc với các API hiện đại, đặc biệt là khi xử lý các bản cập nhật một phần. Và với các công cụ như Apidog, bạn có thể kiểm thử, xác thực và gỡ lỗi các yêu cầu JSON Patch một cách dễ dàng.