3. DICOMweb标准体系总览
DICOMweb 并不是一个单一协议,而是 DICOM 标准第 18 部分(PS3.18)定义的一组基于 HTTP 的 Web 服务集合。它把传统 DIMSE 服务(C-FIND、C-MOVE、C-STORE、C-ECHO 等)重新映射为 RESTful 资源操作,使影像数据能够像普通 Web 资源一样被检索、读取、写入和调度。理解 DICOMweb 的第一步,不是记住每个接口的 URL,而是先分清四类核心服务各自的职责边界:谁负责“找”,谁负责“取”,谁负责“存”,谁负责“调度”。
四类核心服务的职责边界
QIDO-RS(Query based on ID for DICOM Objects – RESTful Services)解决的是“检索元数据”的问题。它对应传统 C-FIND,但只返回匹配对象的属性集合,不返回像素数据。典型查询路径是 /studies、/studies/{studyUID}/series、/studies/{studyUID}/series/{seriesUID}/instances,分别用于按条件查检查、查序列、查实例。QIDO-RS 的返回是 JSON 或 XML 形式的 DICOM 属性列表,例如查询某患者时返回 StudyInstanceUID、StudyDate、Modality、SeriesNumber 等字段。它不负责下载图像,也不负责修改数据。
WADO-RS(Web Access to DICOM Objects – RESTful Services)解决的是“读取对象内容”的问题。它对应传统 C-MOVE/C-GET 的取回语义,但以 HTTP GET 直接返回资源。WADO-RS 可以取回单个实例的完整 DICOM 文件、取回序列中所有实例、取回检查下所有序列,也可以只取回像素数据、元数据或批量帧。例如 /studies/{studyUID}/series/{seriesUID}/instances/{instanceUID} 返回该实例的 multipart/related 响应,其中包含 DICOM 二进制流;而 /frames/1 则用于按帧读取。WADO-RS 是只读服务,不改变服务器状态。
STOW-RS(Store Over the Web – RESTful Services)解决的是“写入对象”的问题。它对应传统 C-STORE,通过 HTTP POST 把 DICOM 实例上传到指定资源路径,如 /studies 或 /studies/{studyUID}。请求体使用 multipart/related 封装一个或多个 DICOM 文件,响应中返回每个实例的存储结果(成功、失败、警告)。STOW-RS 的关键在于幂等性与冲突处理:同一 SOP Instance UID 重复上传时,服务器应依据策略决定覆盖、拒绝或返回已存在状态。
UPS-RS(Unified Procedure Step – RESTful Services)解决的是“工作流调度”的问题。它对应传统 MPPS(Modality Performed Procedure Step)和 GP-WL(General Purpose Worklist),用于创建、查询、更新和取消检查步骤。UPS-RS 的资源路径如 /workitems、/workitems/{workitemUID},支持状态机流转:SCHEDULED → IN PROGRESS → COMPLETED 或 CANCELED。它让影像设备、技师工作站和调度系统之间能够以标准方式协同,而不是各自维护私有工作列表。
RESTful 设计原则如何落地
DICOMweb 的 URL 结构严格遵循资源导向原则:/studies 是检查资源集合,/studies/{studyUID} 是单个检查资源,/series 和 /instances 逐级嵌套。这种层级关系与 DICOM 信息模型(Patient → Study → Series → Instance)完全对应,使开发者能够用直觉理解资源路径。HTTP 方法承担了操作语义:GET 用于查询和读取,POST 用于创建和存储,PUT 用于状态更新,DELETE 用于取消或删除。媒体类型方面,QIDO-RS 使用 application/dicom+json 或 application/dicom+xml,WADO-RS 和 STOW-RS 使用 multipart/related; type="application/dicom",UPS-RS 则使用 application/dicom+json 描述工作项。
一个常见的误区是把 QIDO-RS 当作 WADO-RS 使用,试图通过查询接口直接获取图像像素。正确的做法是:先用 QIDO-RS 拿到 StudyInstanceUID、SeriesInstanceUID 和 SOPInstanceUID,再用 WADO-RS 按 UID 精确读取。另一个误区是忽略 STOW-RS 的响应解析——服务器可能对部分实例返回失败,客户端必须逐条检查响应中的 00081198(Failed SOP Sequence)和 00081190(Retrieve URL),而不是只看 HTTP 状态码 200 就认为全部成功。
服务组合的典型调用链
在实际云影像平台中,四类服务往往组合使用。以“AI 辅助诊断”场景为例:调度系统通过 UPS-RS 创建检查工作项并置为 SCHEDULED;设备完成扫描后,通过 STOW-RS 将影像上传至云存储;AI 服务通过 QIDO-RS 按 Modality 和 StudyDate 检索待处理检查,获取 UID 列表;随后通过 WADO-RS 拉取像素数据或帧数据进行推理;推理完成后,通过 UPS-RS 将工作项状态更新为 COMPLETED,并可选择通过 STOW-RS 回写结构化报告。这条链路中,每个服务只做自己职责内的事,边界清晰,才能保证系统可扩展、可替换。
接口路径与参数示例
下面给出一个可直接参考的调用示例,展示如何用 QIDO-RS 查询某患者 2024 年 6 月之后的检查,再用 WADO-RS 读取第一个序列的元数据:
# 1. QIDO-RS:查询患者检查列表
GET /dicomweb/studies?PatientName=Zhang^San&StudyDate=20240601-20240630
Accept: application/dicom+json
# 响应示例(简化)
[
{
"0020000D": {"vr": "UI", "Value": ["1.2.840.113619.2.55.3.604688.1"]},
"00080020": {"vr": "DA", "Value": ["20240615"]},
"00080061": {"vr": "CS", "Value": ["CT"]},
"00100010": {"vr": "PN", "Value": [{"Alphabetic": "Zhang^San"}]}
}
]
# 2. WADO-RS:读取该检查下第一个序列的元数据
GET /dicomweb/studies/1.2.840.113619.2.55.3.604688.1/series/1.2.840.113619.2.55.3.604688.1.1/metadata
Accept: application/dicom+json
# 3. STOW-RS:上传新实例
POST /dicomweb/studies
Content-Type: multipart/related; type="application/dicom"; boundary=myBoundary
--myBoundary
Content-Type: application/dicom
<DICOM 二进制数据>
--myBoundary--
# 4. UPS-RS:更新工作项状态
PUT /dicomweb/workitems/2.25.1234567890.1/state
Content-Type: application/dicom+json
{
"00741000": {"vr": "CS", "Value": ["IN PROGRESS"]}
}
注意示例中的 DICOM 属性标签采用十六进制表示,这是 DICOMweb JSON 模型的标准写法。QIDO-RS 的查询参数支持通配符 * 和范围查询(如日期区间),但不同服务器对模糊匹配的支持程度可能不同,开发时应以目标服务器的 Conformance Statement 为准。STOW-RS 的 multipart 边界必须与 Content-Type 声明一致,否则服务器会返回 400 错误。UPS-RS 的状态更新必须遵循状态机约束,不能从 SCHEDULED 直接跳到 COMPLETED 而跳过 IN PROGRESS,除非服务器明确允许。
职责边界带来的工程价值
明确四类服务的边界,直接决定了云影像平台的架构质量。如果让 QIDO-RS 承担图像传输,会导致查询接口响应体过大、缓存失效;如果让 WADO-RS 承担写入,会破坏 HTTP 方法的幂等语义;如果让 STOW-RS 承担查询,会造成存储节点负载过高。反过来,按边界拆分后,每个服务可以独立扩展:QIDO-RS 可以部署只读副本并加缓存,WADO-RS 可以接入 CDN 加速像素分发,STOW-RS 可以对接对象存储的分片上传,UPS-RS 可以用轻量数据库支撑高频状态轮询。这种“各司其职、通过 UID 串联”的设计,正是 DICOMweb 相比传统 DIMSE 更适合云原生环境的核心原因。