Chuyển đến nội dung chính

HTTP & FHIR REST API

HIR (Fast Healthcare Interoperability Resources) là tiêu chuẩn trao đổi dữ liệu y tế được phát triển bởi HL7 International. FHIR kết hợp các ưu điểm của các tiêu chuẩn HL7 trước đó (v2.x, v3, CDA) và áp dụng các phương…

HIR (Fast Healthcare Interoperability Resources) là tiêu chuẩn trao đổi dữ liệu y tế được phát triển bởi HL7 International. FHIR kết hợp các ưu điểm của các tiêu chuẩn HL7 trước đó (v2.x, v3, CDA) và áp dụng các phương pháp hiện đại dựa trên web RESTful API. Bài viết này sẽ phân tích chi tiết về cách FHIR sử dụng HTTP để xây dựng REST API.

1. HTTP Methods trong FHIR (GET, POST, PUT, DELETE, PATCH)

FHIR REST API sử dụng các phương thức HTTP tiêu chuẩn để thao tác với tài nguyên y tế. Mỗi phương thức có vai trò và quy tắc sử dụng riêng.

HTTP Methods in FHIR

HTTP Methods in FHIR

GET

GET được sử dụng để đọc (truy xuất) tài nguyên FHIR. Đây là phương thức phổ biến nhất và là phương thức duy nhất mà mọi server FHIR đều phải hỗ trợ.

Ví dụ:

GET https://server.example.com/fhir/Patient/123456

Các biến thể GET:

  • Read: Lấy một tài nguyên cụ thể theo ID
  • Vread: Lấy một phiên bản cụ thể của tài nguyên
  • Search: Tìm kiếm tài nguyên theo các tham số
  • History: Lấy lịch sử thay đổi của tài nguyên
  • Capabilities: Lấy thông tin về khả năng của server

Đặc điểm:

  • Idempotent (thực hiện nhiều lần cho kết quả giống nhau)
  • Không thay đổi dữ liệu trên server
  • Có thể được cache

POST

POST được sử dụng để tạo tài nguyên mới hoặc thực hiện các hoạt động phức tạp.

Ví dụ tạo tài nguyên mới:

POST https://server.example.com/fhir/Patient
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "name": [
    {
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }
  ],
  "gender": "male",
  "birthDate": "1974-12-25"
}

Các biến thể POST:

  • Create: Tạo tài nguyên mới
  • Transaction/Batch: Xử lý nhiều tài nguyên trong một request
  • Operation: Thực hiện các hoạt động tùy chỉnh (ví dụ: $everything, $validate)
  • Search: Tìm kiếm phức tạp với nhiều tham số

Đặc điểm:

  • Không idempotent (có thể tạo ra nhiều tài nguyên khi thực hiện nhiều lần)
  • Thay đổi dữ liệu trên server
  • Không được cache

PUT

PUT được sử dụng để cập nhật tài nguyên hiện có hoặc tạo tài nguyên với ID được chỉ định.

Ví dụ:

PUT https://server.example.com/fhir/Patient/123456
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "123456",
  "name": [
    {
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }
  ],
  "gender": "male",
  "birthDate": "1974-12-25",
  "telecom": [
    {
      "system": "phone",
      "value": "+84123456789",
      "use": "mobile"
    }
  ]
}

Đặc điểm:

  • Idempotent (thực hiện nhiều lần cho kết quả giống nhau)
  • Yêu cầu phải chứa toàn bộ tài nguyên (không cập nhật một phần)
  • Client cần biết ID của tài nguyên
  • Thay thế hoàn toàn tài nguyên hiện có

DELETE

DELETE được sử dụng để xóa tài nguyên FHIR. Trong FHIR, việc xóa có thể là "logical delete" (đánh dấu là đã xóa nhưng vẫn giữ trong lịch sử) hoặc "physical delete" (xóa hoàn toàn).

Ví dụ:

DELETE https://server.example.com/fhir/Patient/123456

Đặc điểm:

  • Idempotent (thực hiện nhiều lần cho kết quả giống nhau)
  • Server có thể từ chối xóa tài nguyên nếu có ràng buộc tham chiếu
  • Nhiều server FHIR thực hiện "logical delete" thay vì xóa hoàn toàn

PATCH

PATCH được sử dụng để cập nhật một phần tài nguyên. Đây là phương thức tùy chọn trong FHIR và không phải tất cả server đều hỗ trợ.

Ví dụ sử dụng JSON Patch:

PATCH https://server.example.com/fhir/Patient/123456
Content-Type: application/json-patch+json

[
  { "op": "replace", "path": "/gender", "value": "female" },
  { "op": "add", "path": "/telecom/0/value", "value": "+84987654321" }
]

Đặc điểm:

  • Không idempotent (kết quả phụ thuộc vào trạng thái hiện tại của tài nguyên)
  • Chỉ cập nhật các trường được chỉ định
  • FHIR hỗ trợ nhiều định dạng patch: JSON Patch, FHIRPath Patch, XML Patch

2. HTTP Status Codes và Ý nghĩa trong FHIR

FHIR sử dụng các mã trạng thái HTTP tiêu chuẩn để truyền đạt kết quả của các hoạt động API. Hiểu được các mã này là cần thiết để xử lý lỗi và xác nhận thành công trong ứng dụng FHIR.

HTTP Status Codes

HTTP Status Codes

Mã thành công (2xx)

MãTênÝ nghĩa trong FHIR
200OKRequest thành công và response chứa tài nguyên được yêu cầu (GET, PUT, POST-search)
201CreatedTài nguyên mới đã được tạo thành công (POST, PUT)
202AcceptedRequest đã được chấp nhận để xử lý bất đồng bộ
204No ContentRequest thành công nhưng không có nội dung trả về (DELETE)

Mã chuyển hướng (3xx)

MãTênÝ nghĩa trong FHIR
304Not ModifiedTài nguyên không thay đổi kể từ lần GET trước (với ETag)

Mã lỗi client (4xx)

MãTênÝ nghĩa trong FHIR
400Bad RequestRequest không hợp lệ (ví dụ: JSON/XML không đúng định dạng)
401UnauthorizedAuthentication cần thiết nhưng không được cung cấp
403ForbiddenNgười dùng đã xác thực nhưng không có quyền truy cập
404Not FoundTài nguyên không tồn tại
405Method Not AllowedPhương thức HTTP không được hỗ trợ cho tài nguyên này
409ConflictXung đột khi cập nhật tài nguyên (ví dụ: version mismatch)
412Precondition FailedĐiều kiện tiên quyết không thỏa mãn (thường liên quan đến version)
422Unprocessable EntityTài nguyên không vượt qua validation
429Too Many RequestsClient gửi quá nhiều requests (rate limiting)

Mã lỗi server (5xx)

MãTênÝ nghĩa trong FHIR
500Internal Server ErrorLỗi server không xác định
501Not ImplementedServer không hỗ trợ chức năng được yêu cầu
503Service UnavailableServer tạm thời không khả dụng (quá tải hoặc bảo trì)
504Gateway TimeoutServer FHIR không nhận được response kịp thời từ upstream server

OperationOutcome

Khi có lỗi, FHIR thường trả về tài nguyên OperationOutcome để cung cấp thông tin chi tiết về lỗi.

Ví dụ:

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "processing",
      "diagnostics": "Patient resource could not be updated due to version conflict"
    }
  ]
}

3. HTTP Headers phổ biến trong FHIR

FHIR sử dụng nhiều HTTP headers để điều khiển hành vi của API và cung cấp metadata.

HTTP Headers

HTTP Headers

Headers trong Request

HeaderMục đíchVí dụ
Content-TypeĐịnh dạng của dữ liệu trong request bodyContent-Type: application/fhir+json
AcceptĐịnh dạng dữ liệu mong muốn trong responseAccept: application/fhir+json
AuthorizationThông tin xác thực (thường là token)Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5...
If-None-MatchChỉ trả về nếu khác với ETag đã choIf-None-Match: W/"3"
If-Modified-SinceChỉ trả về nếu thay đổi sau thời điểmIf-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
If-MatchChỉ thực hiện nếu version/ETag khớpIf-Match: W/"2"
PreferTùy chọn xử lý cho serverPrefer: return=minimal

Headers trong Response

HeaderMục đíchVí dụ
Content-TypeĐịnh dạng của dữ liệu trong response bodyContent-Type: application/fhir+json; charset=utf-8
LocationURI của tài nguyên mới tạoLocation: https://server.example.com/fhir/Patient/123456/_history/1
ETagVersion identifier của tài nguyênETag: W/"3"
Last-ModifiedThời điểm tài nguyên được cập nhật lần cuốiLast-Modified: Wed, 21 Oct 2023 07:28:00 GMT
Content-LocationCanonical URL của tài nguyên được trả vềContent-Location: https://server.example.com/fhir/Patient/123456

FHIR-Specific Headers

HeaderMục đíchVí dụ
X-FHIR-Request-IDID duy nhất cho request (tracing)X-FHIR-Request-ID: 60e0b5d2-c396-4be7-a614-9b3476631051
X-FHIR-Forwarded-ForTương tự như X-Forwarded-ForX-FHIR-Forwarded-For: 203.0.113.195

4. Request và Response Structure

Cấu trúc của request và response FHIR tuân theo chuẩn HTTP với một số quy ước đặc biệt.

Request Structure

1. URL Structure:

FHIR URL có cấu trúc chung như sau:

[base]/[resource-type]/[id]{?[parameters]}

Ví dụ:

  • https://server.example.com/fhir/Patient - Tất cả bệnh nhân
  • https://server.example.com/fhir/Patient/123456 - Bệnh nhân cụ thể
  • https://server.example.com/fhir/Patient?name=nguyễn&gender=male - Tìm kiếm
  • https://server.example.com/fhir/Patient/123456/_history/2 - Version cụ thể
  • https://server.example.com/fhir/Patient/123456/$everything - Operation

2. Headers:

GET https://server.example.com/fhir/Patient/123456
Accept: application/fhir+json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

3. Body (cho POST, PUT, PATCH):

{
  "resourceType": "Patient",
  "id": "123456",
  "meta": {
    "versionId": "2",
    "lastUpdated": "2023-10-21T07:28:00Z"
  },
  "name": [
    {
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }
  ],
  "gender": "male",
  "birthDate": "1974-12-25"
}

Response Structure

1. Headers:

HTTP/1.1 200 OK
Content-Type: application/fhir+json; charset=utf-8
ETag: W/"3"
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT

2. Body:

{
  "resourceType": "Patient",
  "id": "123456",
  "meta": {
    "versionId": "3",
    "lastUpdated": "2023-10-21T07:28:00Z"
  },
  "name": [
    {
      "family": "Nguyễn",
      "given": ["Văn", "A"]
    }
  ],
  "gender": "male",
  "birthDate": "1974-12-25",
  "telecom": [
    {
      "system": "phone",
      "value": "+84123456789",
      "use": "mobile"
    }
  ]
}

Bundles

Khi trả về nhiều tài nguyên (ví dụ từ một search), FHIR sử dụng tài nguyên Bundle:

{
  "resourceType": "Bundle",
  "id": "bundle-example",
  "type": "searchset",
  "total": 2,
  "link": [
    {
      "relation": "self",
      "url": "https://server.example.com/fhir/Patient?name=nguyễn"
    },
    {
      "relation": "next",
      "url": "https://server.example.com/fhir/Patient?name=nguyễn&page=2"
    }
  ],
  "entry": [
    {
      "fullUrl": "https://server.example.com/fhir/Patient/123456",
      "resource": {
        "resourceType": "Patient",
        "id": "123456",
        "name": [
          {
            "family": "Nguyễn",
            "given": ["Văn", "A"]
          }
        ]
      },
      "search": {
        "score": 0.9
      }
    },
    {
      "fullUrl": "https://server.example.com/fhir/Patient/789012",
      "resource": {
        "resourceType": "Patient",
        "id": "789012",
        "name": [
          {
            "family": "Nguyễn",
            "given": ["Thị", "B"]
          }
        ]
      },
      "search": {
        "score": 0.8
      }
    }
  ]
}

Các loại Bundle

FHIR sử dụng các loại Bundle khác nhau cho các mục đích khác nhau:

LoạiMục đích
searchsetKết quả của một search operation
transactionTập hợp các requests thực hiện như một giao dịch
batchTập hợp các requests thực hiện tuần tự
historyLịch sử của tài nguyên
documentBundle đại diện cho một tài liệu lâm sàng
messageBundle đại diện cho một FHIR message
collectionCollection của các tài nguyên

Tổng kết

FHIR REST API dựa trên các nguyên tắc HTTP chuẩn nhưng thêm vào các quy tắc và quy ước đặc biệt cho dữ liệu y tế. Hiểu rõ cách sử dụng các HTTP methods, status codes, headers, và cấu trúc request/response là nền tảng để phát triển và tích hợp thành công với các hệ thống FHIR.

Các điểm quan trọng cần nhớ:

  1. FHIR sử dụng các phương thức HTTP tiêu chuẩn (GET, POST, PUT, DELETE, PATCH) với ngữ nghĩa rõ ràng
  2. Các mã trạng thái HTTP cung cấp thông tin quan trọng về kết quả của request
  3. HTTP headers được sử dụng rộng rãi để kiểm soát hành vi và cung cấp metadata
  4. Các tài nguyên FHIR có thể được biểu diễn dưới nhiều định dạng (JSON, XML) với cấu trúc chuẩn

Trong phần tiếp theo của series, chúng ta sẽ tìm hiểu sâu hơn về các loại tài nguyên FHIR, các tương tác phức tạp, và cách triển khai FHIR trong các dự án y tế thực tế.