← RFC Reference

RFC 8620: JMAP — Giao Thức Ứng Dụng Meta JSON

Standards Track Mail Access Protocols Published March 2026
ELI5: IMAP được thiết kế vào những năm 1990 khi các client giao tiếp với server qua các socket TCP thô với một giao thức văn bản tùy chỉnh. JMAP là cùng một ý tưởng — truy cập hộp thư của bạn, quản lý thư mục, đồng bộ hóa thay đổi — nhưng sử dụng các công cụ mà mọi nhà phát triển đã biết: JSON qua HTTPS. Đó là một API kiểu REST cho email. Không quản lý socket, không phân tích các phản hồi văn bản khó hiểu, không đàm phán phần mở rộng. Chỉ cần POST một yêu cầu JSON, nhận một phản hồi JSON.

Tại sao nó tồn tại

IMAP hoạt động, nhưng nó mang theo độ phức tạp của nhiều thập kỷ:

JMAP giải quyết tất cả những điều này. Nó không có trạng thái (mỗi yêu cầu tự chứa), sử dụng HTTPS (hoạt động qua mọi proxy và firewall), sử dụng JSON (mỗi ngôn ngữ có một trình phân tích cú pháp), và xác định thông báo đẩy như một tính năng hạng nhất thông qua EventSource hoặc Web Push.

Nó hoạt động như thế nào

Khám phá dịch vụ

Một client khám phá điểm cuối JMAP thông qua một URI được xác định tốt:

GET https://example.com/.well-known/jmap
{
  "capabilities": {
    "urn:ietf:params:jmap:core": { ... },
    "urn:ietf:params:jmap:mail": { ... }
  },
  "apiUrl": "https://jmap.example.com/api/",
  "uploadUrl": "https://jmap.example.com/upload/{accountId}/",
  "downloadUrl": "https://jmap.example.com/download/{accountId}/{blobId}/{name}",
  "eventSourceUrl": "https://jmap.example.com/events/"
}

Thực hiện lệnh gọi API

Tất cả các hoạt động JMAP được gửi dưới dạng một POST duy nhất tới URL API. Phần thân yêu cầu chứa một mảng các lệnh gọi phương thức, và phản hồi chứa các kết quả tương ứng:

POST https://jmap.example.com/api/
{
  "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
  "methodCalls": [
    ["Mailbox/get", { "accountId": "u1234", "ids": null }, "a"]
  ]
}

{
  "methodResponses": [
    ["Mailbox/get", {
      "accountId": "u1234",
      "state": "m42",
      "list": [
        { "id": "mb1", "name": "Inbox", "totalEmails": 142 },
        { "id": "mb2", "name": "Sent", "totalEmails": 87 },
        { "id": "mb3", "name": "Archive", "totalEmails": 4210 }
      ]
    }, "a"]
  ]
}

Đóng gói và tham chiếu ngược

Có thể đóng gói nhiều lệnh gọi phương thức trong một yêu cầu duy nhất. Các tham chiếu ngược cho phép một lệnh gọi sử dụng kết quả của lệnh gọi trước đó:

"methodCalls": [
  ["Email/query", {
    "accountId": "u1234",
    "filter": { "inMailbox": "mb1", "after": "2025-03-01T00:00:00Z" },
    "sort": [{ "property": "receivedAt", "isAscending": false }],
    "limit": 10
  }, "q"],
  ["Email/get", {
    "accountId": "u1234",
    "#ids": { "resultOf": "q", "name": "Email/query", "path": "/ids" },
    "properties": ["from", "subject", "receivedAt", "preview"]
  }, "g"]
]

Điều này tìm kiếm hộp thư đến và tìm nạp 10 kết quả hàng đầu trong một vòng HTTP duy nhất — điều gì sẽ mất nhiều lệnh IMAP.

Chi tiết kỹ thuật chính

Chuỗi trạng thái và đồng bộ hóa

Mỗi phản hồi JMAP /get bao gồm một chuỗi state. Để đồng bộ hóa các thay đổi, client gọi /changes với trạng thái được biết lần cuối:

["Email/changes", { "accountId": "u1234", "sinceState": "e789" }, "c"]

["Email/changes", {
  "oldState": "e789",
  "newState": "e801",
  "created": ["em500", "em501"],
  "updated": ["em480"],
  "destroyed": ["em312"]
}, "c"]

Client sau đó tìm nạp chỉ các mục được tạo/cập nhật. Điều này hiệu quả hơn CONDSTORE của IMAP vì nó hoạt động trên tất cả các hộp thư cùng một lúc và không yêu cầu một kết nối liên tục.

Thông báo đẩy

JMAP xác định hai cơ chế đẩy:

Mô hình Foo/get, Foo/set, Foo/query

JMAP sử dụng một mô hình phương thức thống nhất cho mỗi loại dữ liệu:

Phương thức Mục đích
Foo/get Tìm nạp các đối tượng theo ID
Foo/changes Lấy ID của các đối tượng đã thay đổi kể từ một trạng thái
Foo/set Tạo, cập nhật, hoặc xóa các đối tượng
Foo/query Tìm kiếm/lọc và sắp xếp, trả về ID phù hợp
Foo/queryChanges Cập nhật tăng dần cho kết quả truy vấn trước đó

Đối với email, FooEmail, Mailbox, Thread, EmailSubmission, v.v. Tính nhất quán này có nghĩa là một khi bạn hiểu được một loại dữ liệu, bạn sẽ hiểu được tất cả chúng.

Những sai lầm phổ biến

Tác động khả năng giao hàng

Related RFCs