JSON Patch: Cách Thông Minh Để Cập Nhật Dữ Liệu API

INEZA Felin-Michel

INEZA Felin-Michel

1 tháng 9 2025

JSON Patch: Cách Thông Minh Để Cập Nhật Dữ Liệu API

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 công cụ kiểm thử API tuyệt vời tạo ra Tài liệu API đẹp mắt?

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!
nút

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:

  1. 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.
  2. 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ửa email của mình, yêu cầu PUT 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.
  3. 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, movecopy.

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.

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:

JSON Merge Patch:

Tóm lại:

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 removeadd 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

Tại sao các API sử dụng JSON Patch

Các API yêu thích JSON Patch vì nó:

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:

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:

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á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.

  1. 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).
  2. 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ặc 400 Bad Request).
  3. 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:

nút

Quy trình làm việc ví dụ trong Apidog:

  1. Tạo một yêu cầu mới.
  2. Đặt phương thức thành PATCH.
  3. Thêm Content-Type: application/json-patch+json.
  4. Nhập mảng JSON Patch của bạn.
  5. 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ả:

  1. Xác thực các tài liệu JSON Patch của bạn trước khi gửi.
  2. Sử dụng các thao tác kiểm tra khi tính nhất quán là quan trọng.
  3. Giữ các bản vá nhỏ để đạt hiệu quả.
  4. Tài liệu hóa API của bạn rõ ràng khi sử dụng JSON Patch.
  5. 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.

nút

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API