Current Build

Переводит компания Health Samurai . Приглашаем поучаствовать в русификации стандарта FHIR: GitHub , Email.

FHIR Infrastructure Рабочая группаУровень зрелости: 5Статус голосования: Пробное использование

FHIR is described as a 'RESTful' specification based on common industry level use of the term REST. In practice, FHIR only supports Level 2 of the REST Maturity model as part of the core specification, though full Level 3 conformance is possible through the use of extensions. Because FHIR is a standard, it relies on the standardization of resource structures and interfaces. This may be considered a violation of REST principles but is key to ensuring consistent interoperability across diverse systems.

В FHIR описан определенный набор взаимодействий, с использованием которого можно достаточно тонко управлять разными типами ресурсов. Приложения, которые заявляют поддержку FHIR, должны реализовать "RESTful API" спецификацию (см. Conformance).

В рамках RESTful взаимодействий, транзакции происходят на сервере с помощью HTTP запросов и ответов. Спецификация не описывает детали аутентификации, авторизации и аудита (для более детальной информации см. Security Page).

API состоит из набора операций (взаимодействий) над ресурсами, которые сгруппированы по типам в коллекции. Серверы могут выбирать, какие из этих операций делать доступными и какие типы ресурсов они поддерживают. Серверы ДОЛЖНЫ предоставлять Capability Statement, в котором указывать поддерживаемые операции и ресурсы.

Определен следующий набор логических операций:

Операции на уровне ресурсов
readПолучение текущего состояния ресурса
vreadПолучение конкретной версии ресурса
updateОбновление ресурса по идентификатору (или создание, если его еще нет)
patchUpdate an existing resource by posting a set of changes to it
deleteУдаление ресурса
historyПолучение истории изменений определённого ресурса
Операции на уровне типов
createСоздание нового ресурса (id назначает сервер)
searchПоиск среди ресурсов одного типа по разным критериям
historyПолучение полной истории для ресурсов определенного типа
Операции общесистемного уровня
capabilitiesПолучение заявления о соответствии системы
batch/transactionОбновление, создание или удаление нескольких ресурсов в рамках одной транзакции
historyПолучении истории изменений всех ресурсов
searchПоиск по ресурсам всех типов по разным критериям

Кроме этих взаимодействий, имеется operations framework, который включает в себя точки взаимодействия для валидации, отправки сообщений и документов. Также реализаторы могут использовать GraphQL.

Оформление

Взаимодействия описываются на этой странице следующим образом:

  VERB [base]/[type]/[id] {?_format=[mime-type]}
  • Сначала идёт название HTTP-метода, используемого в операции
  • Текст в квадратных скобочках [] является обязательным, он будет замещён строковым литералом. Возможные значения:
  • Текст внутри фигурных скобок {} является необязательным.

Реализации, строящие URL-адреса по этим шаблонам, ДОЛЖНЫ соответствовать RFC 3986 Section 6 Appendix A , который требует процентной кодировки для некоторых символов, которые иногда появляются в URL-адресах (преимущественно в параметрах поиска).

В спецификации для зарезервированных имён используется символ подчёркивания в трёх случаях:

  • чтобы отличать операции запроса истории изменений и поиска системного уровня от операций над типами ресурсов;
  • чтобы отличать операции поиска, истории изменений и подобных взаимодействий от экземпляров типа ресурса;
  • чтобы отличать параметры поиска, определённые для всех ресурсов, от операций, определенных для конкретных типов ресурсов.

Дополнительно используется символ $ в качестве префикса названий RPC-подобных операций, являющихся дополнительными к базовому API, определённому спецификацией или реализаторами.

Базовый URL сервиса - это адрес, по которому можно обращаться к определенным интерфейсом ресурсам. Он имеет следующий формат:

http(s)://server{/path}

Часть {/path} не обязательна и не должна содержать "/" (слэш) в конце. Каждый тип ресурсов в спецификации имеет свою точку взаимодействия (или "набор сущностей"), доступную по адресу /[type], где [type] - это имя типа ресурса. Например, точка взаимодействия для типа "Patient" будет иметь следующий адрес:

https://server/path/Patient

Все логические операции определены относительно базового URL. Т. е. если известен адрес одного FHIR-ресурса системы, всегда можно вычислить адрес другого.

Примечание: все URL (и идентификаторы, являющиеся частью этих URL), определённые в спецификации, чувствительны к регистру. Clients SHOULD encode URLs using UTF-8, and servers SHOULD decode them assuming they are UTF-8 (for background, see here ).

Обратите внимание, что сервер может использовать пути типа "http://server/...[xx]...", где [xx] - это некоторая переменная часть, идентифицирующая конкретный экземпляр реализации FHIR API. Обычно это идентификатор пациента или пользователя, и его присутствие означает, что вся информация относится к данному пациенту/пользователю либо персонализирована для него. Так, в случае пользователя это означает, что именно ему предоставлен явный доступ к операции. Не обязательно всегда включать идентификатор пациента в URL - реализации могут связывать точку взаимодействия FHIR с конкретным пациентом или провайдером с помощью OAuth. Логическое обоснование можно посмотреть в Compartments.

Идентификация

Системы часто сталкиваются с задачей сравнения двух URL-адресов для определения того, ведут ли они на один и тот же адрес или нет. В рамках данной спецификации применяются следующие правила:

  • Часть URL, содержащая запрос (всё, что идёт после '?'), игнорируется
  • Сравнение документной части URL (т. е. не сервер или порт) чувствительно к регистру
  • http: и https: взаимозаменяемы и относятся к одному объекту
  • Если задан порт, то порты должны совпадать, иначе это различные объекты (относится к распространенному мэппингу портов и/или работе запущенных интерфейсов на разных портах). Порты надо указывать явно, только когда они имеют значение для сервера

Например: http://myserver.com/Patient/1 и https://myserver.com/Patient/1 ведут на один и тот же лежащий в их основе объект, а http://myserver.com:81/Patient/1 - это отличная от этих двух адресов сущность. Это не означает, что эти два адреса необходимо считать одинаковыми, или что сервер должен обслуживать оба эти адреса, или что содержимое по этим двум адресам должно быть идентичным, а показывает только, что если эти два адреса тождественны и если оба они обслуживаются, они должны представлять собой один и тот же лежащий в их основе объект. Системы не обязаны проверять, что это верно. Примечание: сравнение идентичности для протоколов помимо http:/https: не определено.

Каждый ресурс имеет связанный с ним набор метаданных, которые передаются в запросах и ответах в следующих полях:

Metadata ItemWhere found in HTTP
Logical Id (.id)The Id is represented explicitly in the URL
Version Id (.meta.versionId)The Version Id is represented in the ETag header
Last modified (.meta.lastUpdated)HTTP Last-Modified header

Обратите внимание, что Version Id считается «слабым» ETag-ом и ETag -заголовки должны быть с префиксом "W/" и заключены в кавычки, например:

ETag: W/"3141"

Использование HTTPS является необязательным, но для передачи любых реальных медицинских данных ДОЛЖЕН использоваться SSL и, при необходимости, другие дополнительные предосторожности. См. Безопасность HTTP для более детальной информации.

См. руководство HTTP Security о том, как обрабатывать ответ с отказом в доступе.

Примечание: для поддержки браузерных клиентских приложений сервер ДОЛЖЕН реализовывать Кросс-доменный доступ к ресурсам для прведенных здесь операций. Практика показывает, что в этой области следует постоянно ожидать проблем по мере того, как обнаруживаются и закрываются дырки в системе безопасности.

Данная спецификация описывает использование определенных кодов состояния (status codes). Другие коды (не описанные в спецификации) могут быть использованы, когда код не ясен или его использование подходит по семантике HTTP (обычно это коды, связанные с аутентификацией, авторизацией и перенаправлением (redirect). Перенаправление для аутентификации не должно быть интерпретировано как изменение адреса ресурса (часто встречающаяся ошибка).

FHIR определяет специальный ресурс OperationOutcome, который может быть использован для структурированного описания ошибок. OperationOutcome должен быть включен в ответ для определенных случаев, описанных в спецификации. Также его опционально можно использовать в качестве тела ответа на ошибочные запросы с кодами 4xx or 5xx, однако это не обязательно - большинство этих ошибок могут генерироваться фреймворками сервера общего вида, лежащими в основе FHIR-сервера.

В интересах управления пропускной способностью данная спецификация позволяет клиентам указывать тип возвращаемого контента.

Клиенты могут использовать HTTP-заголовок If-Modified-Since или If-None-Match в запросе на read. В этом случае они ОБЯЗАНЫ принимать или 304 Not Modified в качестве допустимого кода состояния в ответе (который означает, что содержимое не менялось с этой даты), или содержимое целиком (либо содержимое поменялось, либо сервер не поддерживает условные запросы).

Серверы могут вернуть код состояния 304 Not Modified, если содержимое не менялось с даты/времени, указанной в If-Modified-Since или If-None-Match ETag, либо они могут вернуть содержимое целиком как обычно. Такая оптимизация актуальна при уменьшении пропускной способности для кеширования, и серверам рекомендуется, но не требуется поддерживать её.

Эти операции выполняются с помощью POST,PUT or PATCH, и для сервера может быть уместно возвращать либо только статус-код, либо также сам ресурс целиком, что будет являться результатом операции create или update (которые могут отличаться от того, что предоставляется клиентом). В случае транзакций это означает вернуть Bundle с Bundle.entry.transactionResponse, а не Bundle.entry.resource.

Клиент может указать, вернётся ли ресурс целиком, с помощью предпочтения возврата HTTP :

Prefer: return=minimal
Prefer: return=representation
Prefer: return=OperationOutcome

Первая настройка просит не возвращать body. Вторая просит вернуть полный ресурс. Третья запрашивает сервер вернуть ресурс OperationOutcome, содержащий подсказки и предупреждения об этой операции, а не сам запрашиваемый ресурс. Servers SHOULD honor this header. In the absence of the header, servers may choose whether to return the full resource or not (but not the OperationOutcome; that should only be returned if explicitly requested). Note that this setting only applies to successful interactions. In case of failure, servers SHOULD always return a body that contains an OperationOutcome resource.

Формальным MIME-типом для FHIR-ресурсов является application/fhir+xml или application/fhir+json. Корректный MIME-тип ДОЛЖЕН использоваться клиентами и серверами:

  • XML: application/fhir+xml
  • JSON: application/fhir+json
  • RDF: text/turtle (only the Turtle format is supported)

Сервер ДОЛЖЕН поддерживать серверное согласование форматов (content negotiation), как описано в секции 12 спецификации HTTP.

Note: between FHIR DSTU2 and STU3, the correct mime type was changed from application/xml+fhir and application/json+fhir to application/fhir+xml and application/fhir+json. Servers MAY also support the older mime types, and are encouraged to do so to smooth the transtion process.

In order to support various implementation limitations, servers SHOULD support the optional _format parameter to specify alternative response formats by their MIME-types. This parameter allows a client to override the accept header value when it is unable to set it correctly due to internal limitations (e.g. XSLT usage). For the _format parameter, the values xml, text/xml, application/xml, and application/fhir+xml SHALL be interpreted to mean the XML format, the codes json, application/json and application/fhir+json SHALL be interpreted to mean the JSON format, and the codes ttl and text/turtle SHALL be interpreted to mean the Turtle RDF format. In addition, the values html and text/html are allowed.

FHIR использует UTF-8 для всех запросов и ответов. Поскольку по умолчанию спецификация HTTP (section 3.7.1) считается ISO-8859-1, кодировка UTF-8 ДОЛЖНА быть явно выставлена для всех запросов и ответов с использованием параметра charset в заголовке Content-Type. Запрос также МОЖЕТ указать параметр charset в заголовке Accept или использовать заголовок Accept-Charset.

Примечание: параметр _format не перезаписывает заголовок content-type.

Тип содержимого application/x-www-form-urlencoded также допустим для отправки search-запросов [командой POST].

Если ни accept-заголовок, ни параметр _format не указаны, то MIME-тип содержимого, возвращаемого сервером, считается неопределённым и может варьироваться.

Implementation Note: If a client provides a generic mime type in the Accept header (application/xml, text/json, or application/json), the server SHOULD respond with the requested mime type, using the XML or JSON formats described in this specification as the best representation for the named mime type (though see the note on the Binary resource).

Серверам, поддерживающим этот API, СЛЕДУЕТ обеспечивать полную поддержку версий - то есть корректно заполнять и отслеживать versionId, поддерживать операцию vread и осуществлять учитывающие версию обновления. Такая поддержка версионирования позволяет связанным системам отслеживать корректную версию информации и сохранять целостность медицинских записей. Однако большинство современных операционных систем не делают этого и не могут быть легко модернизированы, чтобы делать это.

По этой причине серверам позволяется не предоставлять поддержку версионирования: этот API не навязывает того, чтобы они поддерживались. Клиенты могут выбрать взаимодействовать только с серверами, которые предоставляют полную поддержку версионирования. Системы объявляют о поддержке версионирования в своих Capability Statements. Where they can indicate one of three levels for versioning support:

  • no-version: Versioning and meta.version is not supported (server) or used (client)
  • versioned: Versioning and meta.version is supported (server) or used (client)
  • versioned-update: Versioning and meta.version is supported, and version aware updates are used - Version ID must be correct for updates (server) or will be specified (If-match header) for updates (client)

Сервер всегда должен возвращать дефолтную таймзону в HTTP-заголовке ответа Date при поиске по датам. Примечание: Серверы не обязаны иметь дефолтную таймзону.

Взаимодействие read (операция чтения данных) позволяет получить текущее содержимое ресурса. Для этого надо послать GET запрос по адресу:

  GET [base]/[type]/[id] {?_format=[mime-type]}

В ответ сервер присылает содержимое соответствующего типа. Этот адрес может быть доступен из браузера. Возможные значения для логического идентификатора (Logical Id; id) описаны в секции идентификационный тип. Возвращаемый ресурс ДОЛЖЕН иметь элемент id со значением [id]. Серверам СЛЕДУЕТ возвращать заголовок ETag с versionId и заголовок Content-Location с ответом, представляющим собой полный URL, включающий версию (смотри "vread" ниже) и заголовок Last-Modified с датой последней модификации.

Примечание: если осуществляется попытка чтения GET неизвестного ресурса, сервер должен вернуть статус 404, а для удаленного ресурса - 410, соответственно. Системы, которые не отслеживают удаленные ресурсы, могут считать удаленный ресурс не существующим.

Дополнительно при чтении ресурса можно использовать параметр поиска _summary:

  GET [base]/[type]/[id] {?_summary=text}

Это запрос что только подмножество содержимого ресурса будет возвращено, как указано в параметре _summary, который может иметь значения true, false, text & data. Отметьте, что ресурс, который содержит только подмножество данных, не подходит для использования в качестве основы для обновления ресурса, и может не подходить для других целей. То же применимо и к параметру _elements - и то, что его следует поддерживать, и все вытекающие из этого выводы. Серверам СЛЕДУЕТ использовать Simple Tag SUBSETTED, чтобы явным образом помечать такие ресурсы.

Взаимодействие vread (операция чтения данных определенной версии) выполняет чтение ресурса определенной версии. Операция выполняется HTTP-командой GET, как показано ниже:

  GET [base]/[type]/[id]/_history/[vid] {?_format=[mime-type]}

Эта команда возвращает одиночный экземпляр с содержимым, указанным для этого типа ресурса и этой версии ресурса. Возвращаемый ресурс ДОЛЖЕН иметь элемент id со значением [id], и элемент meta.versionId со значением [vid]. Серверам СЛЕДУЕТ возвращать ETag-заголовок с versionId (если версионирование поддержано) и заголовок Last-Modified.

Version Id (vid) - это непрозрачный идентификатор, соответствующий тем же требованиям к формату, что и Logical Id. Этот id может быть найден с помощью выполнения операции history (см. ниже), с помощью записи version id в местонахождении содержимого, возвращенного операцией read, либо в ссылке на конкретную версию в модели содержимого. Если это ссылка на версию, в которой этот ресурс был удален, то серверу следует вернуть код состояния 410.

Серверам рекомендуется поддерживать получение конкретной версии ресурса из текущей, даже если они не предоставляют доступ к предыдущим версиям. Если получен запрос на предыдущую версию ресурса, и сервер не поддерживает доступ к предыдущим версиям (либо в общем, либо для этого конкретного ресурса), он должен вернуть ошибку 404 Not Found наряду с результатом операции, поясняющим, что операция history не поддерживается для такого типа или экземпляра ресурса.

Взаимодействие update (операция обновления) создает новую текущую версию для существующего ресурса, либо создает первоначальную версию, если для данного идентификатора еще не существует ресурс. Взаимодействие update выполняется HTTP-командой PUT, как показано ниже:

  PUT [base]/[type]/[id] {?_format=[mime-type]}

Телом запроса должен быть ресурс с элементом id, имеющим идентичное значение, что и [id] в URL. Если элемент id не указан, либо значение неправильное, сервер должен вернуть HTTP-код ошибки 400 и ресурс OperationOutcome с описанием ошибки. Если тело запроса содержит meta, сервер ДОЛЖЕН игнорировать предложенные значения versionId и lastUpdated. Если сервер поддерживает версионирование, он ДОЛЖЕН заполнить meta.versionId и meta.lastUpdated новыми корректными значениями. Серверам разрешается проверять и изменять другие значения метаданных, но СЛЕДУЕТ воздерживаться от этого (см. более подробную информацию на странице описания метаданных). Отметьте, что нет поддержки обновления предыдущих версий - см. примечания к операции history.

Сервер ДОЛЖЕН принимать ресурс в том виде, в каком он был отправлен на сервер, когда допускает обновление, и возвращать то же самое содержимое, когда он впоследствии читается. Однако системы могут не иметь возможности делать это; см. примечание к обсуждению в разделе Транзакционная целостность. Note that update genreally updates the whole content of the resource. For partial updates, see patch below.

Если операция прошла успешно, сервер ДОЛЖЕН вернуть либо HTTP статус-код 200 OK, если ресурс был обновлен, либо статус-код 201 Created, если ресурс был создан, с заголовком Last-Modified и заголовком ETag, который содержит новый versionId ресурса. Заголовок Content-Location, который указывает на конкретную версию, созданную операцией update, ДОЛЖЕН также быть возвращен. Если ресурс был создан (т. е. результатом операции был статус-код 201 Created), сервер ДОЛЖЕН вернуть заголовок Location.

Примечание: серверы МОГУТ решить сохранять XML-комментарии, инструкции и форматирование или JSON-табуляцию, когда принимают операции обновления, однако не обязаны это делать. Может потребоваться учитывать влияние этого на электронные цифровые подписи.

Отметьте, что серверы МОГУТ по желанию разрешать клиентам размещать ресурс командой PUT по адресу, который ещё не существует на этом сервере - эффективно, позволяя клиенту задавать идентификатор этого ресурса. Выбор того, будет ли сервер позволять это делать, делается во время его инсталляции на основе характера взаимосвязи с клиентами. Хотя большинство серверов не позволяют клиентам задавать свои идентификаторы, есть несколько причин, почему это может оказаться необходимым в некоторых конфигурациях.

  • клиент воспроизводит существующую модель данных на сервере, и ему необходимо сохранить оригинальные идентификаторы, чтобы сохранить непрерывную целостность
  • клиентом является сервер, выполняющий push на основе pub/sub (это особый случай первой причины)
  • несколько клиентов выполняют push в контексте согласованной модели данных, совместно используемой несколькими серверами, в которой идентификаторы расшарены между серверами

В качестве альтернативы клиенты могут совместно использовать согласованную модель идентификации (например сервер ключей, идентификаторы с областью видимости, UUID), в которой не будут возникать конфликты.

Серверы могут выбирать, поддерживать или нет задание идентификаторов клиентами, и сообщать об этом клиентам с помощью CapabilityStatement.rest.resource.updateCreate.

Серверам разрешается отклонять операцию update в связи с вопросами целостности или другими бизнес-правилами, применяемыми на сервере, и возвращать соответствующий HTTP код состояния (обычно 422).

Распространённые HTTP коды состояния, возвращаемые в случае связанных с FHIR ошибок (в дополнение к обычным HTTP ошибкам, связанным с вопросами согласования безопасности, заголовков и типов контента):

  • 400 Bad Request - невозможно выполнить синтаксический разбор ресурса, либо ресурс не соответствует основным правилам валидации FHIR (или критериям запроса соответствует несколько ресурсов)
  • 401 Not Authorized - требуется авторизация
  • 404 Not Found - тип ресурса не поддерживается, либо это не точка взаимодействия FHIR
  • 405 Method Not allowed - ресурс не существует на момент обновления, и сервер не разрешает определенные клиентом идентификаторы
  • 409/412 - конфликт версий - см ниже
  • 422 Unprocessable Entity - предложенный ресурс нарушает применимые профили FHIR или бизнес-правила сервера

Каждая из этих ошибок ДОЛЖНА сопровождаться ресурсом OperationOutcome, подробно описывающим произошедший сбой.

Для получения дополнительной информации о том, как системы могут вести себя при обработке обновления, обратитесь к странице Механизм создания и обновления .

Операция условного обновления позволяет клиенту обновить существующий ресурс на основе некоторых идентификационных критериев, а не по logical id. Для выполнения этого клиент создает PUT:

  PUT [base]/[type]?[search parameters]

Когда сервер обрабатывает это обновление, он выполняет поиск с помощью своих стандартных средств поиска по типу ресурса с целью разрешения отдельного logical id для этого запроса. Следующее действие сервера зависит от того, сколько совпадений он нашел:

  • Нет совпадений: Сервер выполняет операцию create
  • Одно совпадение: Сервер выполняет обновление найденного ресурса
  • Несколько совпадений: Сервер возвращает ошибку 412 Precondition Failed, означающую, что критерии клиента не были достаточно селективными

Этот вариант может использоваться, чтобы дать возможность stateless-клиенту (без запоминания состояния; такому как интерфейсная машина - interface engine) отправить обновленные результаты на сервер без необходимости помнить логические идентификаторы, которые назначил сервер. Например клиент, обновляющий статус лабораторного результата с "preliminary" на "final", мог бы отправить окончательный результат с помощью PUT path/Observation?identifier=http://my-lab-system|123

Отметьте, что транзакции и условные операции create/update/delete являются комплексными взаимодействиями, и не предполагается, что каждый сервер будет их реализовывать. Серверы, которые не поддерживают условное обновление, должны возвращать HTTP-код ошибки 400 и результат операции OperationOutcome.

Ситуацию потери обновлений , когда два клиента обновляют один и тот же ресурс, и второй перезаписывает изменения первого, можно предотвратить, используя комбинацию заголовков ETag и If-Match . This is also known as 'Optimistic Locking'.

Для поддержки этого метода серверам СЛЕДУЕТ всегда возвращать заголовок ETag с каждым ресурсом:

HTTP 200 OK
Date: Sat, 09 Feb 2013 16:09:50 GMT
Last-Modified: Sat, 02 Feb 2013 12:02:47 GMT
ETag: W/"23"
Content-Type: application/fhir+json

Если указано, значение ETag ДОЛЖНО совпадать со значением version id ресурса. Серверам разрешается генерировать version id каким угодно образом при условии, что они являются допустимыми в соответствии с типом данных id и уникальными в пределах адресного пространства всех версий одного ресурса. Когда ресурсы возвращаются в рамках комплекта, ETag отсутствует, и используется непосредственно versionId ресурса.

Если клиент хочет запросить версионное обновление, он отправляет запрос с заголовком If-Match, который цитирует ETag с сервера:

PUT /Patient/347 HTTP/1.1
If-Match: W/"23"

Если version id, заданный в заголовке If-Match, не совпадает, сервер возвращает код состояния 412 Pre-condition failed вместо обновления ресурса.

Серверы могут требовать, чтобы клиенты предоставляли заголовок If-Match, возвращая код состояния 412 Pre-condition failed, когда заголовок If-Match отсутствует.

As an alternative to updating an entire resource, clients can perform a patch operation. This can be useful when a client is seeking to minimise it's bandwidth utilization, or in scenarios where a client has only partial access or support for a resource. The patch interaction is performed by an HTTP PATCH command as shown:

  PATCH [base]/[type]/[id] {?_format=[mime-type]}

The body of a PATCH operation SHALL be either:

In either case, the server SHALL process its own copy of the resource in the format indicated, applying the operations specified in the document, following the relevant PATCH specification. When the operations have all been processed, the server processes the resulting document as an Update operation; all the version and error handling etc. applies as specified, as does the Prefer Header.

Processing PATCH operations may be very version sensitive. For this reason, servers SHALL support conditional PATCH, which works exactly the same as specified for update in Concurrency Management. Clients SHOULD always consider using version specific PATCH operations so that inappropriate actions are not executed. In addition, servers SHALL support Conditional PATCH, which works exactly as described for Conditional Update.

The server SHALL ensure that the narrative in a resource is not clinically unsafe after the PATCH operation is performed. Exactly how this is defined and can be achieved depends on the context, and how narrative is being maintained, but servers may wish to consider:

  • If the existing narrative has a status != generated, the server could reject the PATCH operation
  • The server could regenerate the narrative once the operation has been applied to the data
  • In some limited circumstances, an XML PATCH operation could update the narrative
  • The server could delete the narrative, on the basis that some later process will be able to populate it correctly

Processing XML Patch documents is tricky because of namespace handling. Servers SHALL handle namespaces correctly, but note that FHIR resources only contain two XML namespaces, for FHIR (http://hl7.org/fhir) and XHTML (http://www.w3.org/1999/xhtml).

For PATCH Examples, see (link todo).

Patch operations may be performed as part of Batch or Transaction Operations using the FHIRPath Patch format.

Взаимодействие delete (операция удаления) удаляет существующий ресурс. Операция выполняется HTTP-командой DELETE, как показано ниже:

  DELETE [base]/[type]/[id]

A delete interaction means that subsequent non-version specific reads of a resource return a 410 HTTP status code and that the resource is no longer found through search interactions. Upon successful deletion, or if the resource does not exist at all, the server should return either a 200 OK if the response contains a payload, or a 204 No Content with no response payload.

Whether to support delete at all, or for a particular resource type or a particular instance is at the 200 OK if the response contains a payload, or a 204 No Content with no response payload. Resources that have been deleted may be "brought back to life" by a subsequent update interaction using an HTTP PUT.

Большинство ресурсов имеют элемент status, который пересекается с идеей удаления. Каждый тип ресурса определяет свою семантику операции удаления. Если документация не предоставлена, операцию удаления следует понимать как удаление записи ресурса без каких-либо последствий на состояние соответствующего реального ресурса.

Для серверов, которые поддерживают историю версий, операция delete не удаляет историю версий ресурса. С точки зрения истории версий, удаление ресурса эквивалентно созданию особого вида записи в истории, которая не имеет содержимого и помечена как удаленная. Note that there is no support for deleting past versions - see notes on the history interaction.

Поскольку удалённые ресурсы могут быть восстановлены, серверы МОГУТ включать ETag в ответ на операцию удаления, чтобы избежать конфликтов версий, когда ресурс будет восстановлен.

Операция условного удаления позволяет клиенту обновить существующий ресурс на основе некоторых идентификационных критериев, а не по logical id. Для выполнения этой операции клиент выполняет HTTP DELETE:

  DELETE [base]/[type]/?[search parameters]

Когда сервер обрабатывает это обновление, он выполняет поиск, как указано, используя стандартные средства поиска по типу ресурса. Следующее действие сервера зависит от того, сколько совпадений было найдено:

  • Нет совпадений или Одно совпадение: Сервер выполняет обычную операцию delete над найденным ресурсом
  • Несколько совпадений: Сервер возвращает ошибку 412 Precondition Failed, означающую, что критерии клиента не были достаточно селективными. Сервер указывает, может ли он удалять сразу несколько ресурсов в своём Capability Statement (.rest.resource.conditionalDelete). Если есть несколько совпадений, то либо все должны быть удалены, либо сервер ДОЛЖЕН вернуть ошибку

Этот вариант может использоваться, чтобы дать возможность stateless-клиенту (без запоминания состояния; такому как интерфейсная машина - interface engine) удалить ресурс на сервере без необходимости помнить логические идентификаторы, которые назначил сервер. Например клиент, удаляющий атомарный лабораторный результат, мог бы удалить ресурс с помощью DELETE /Observation?identifier=http://my-lab-system|123.

Отметьте, что транзакции и условные операции create/update/delete являются комплексными взаимодействиями, и не предполагается, что каждый сервер будет их реализовывать. Серверы, которые не поддерживают условное обновление, должны возвращать HTTP-код ошибки 400 и результат операции OperationOutcome.

Взаимодействие create (операция создания) создает новый ресурс в назначенном сервером месте. Если клиент хочет контролировать id создаваемого ресурса, ему следует использовать вместо этого операцию update. Взаимодействие create выполняется HTTP-командой POST, как показано ниже:

  POST [base]/[type] {?_format=[mime-type]}

Телом запроса ДОЛЖЕН быть FHIR-ресурс. Этому ресурсу не обязательно иметь элемент id (это один из немногих случаев, когда ресурс существует без элемента id). Если элемент id всё же указан, то сервер ДОЛЖЕН его игнорировать. Если тело запроса содержит meta, сервер ДОЛЖЕН игнорировать существующие значения versionId и lastUpdated. Сервер ДОЛЖЕН заполнить элементы id, meta.versionId и meta.lastUpdated новыми корректными значениями. Серверам разрешается проверять и изменять другие значения метаданных, но СЛЕДУЕТ воздерживаться от этого (см. более подробную информацию на странице описания метаданных).

В ином случае сервер ДОЛЖЕН принять ресурс в том виде, в котором он был отправлен, когда он разрешает операцию create, и возвращать то же самое содержимое, когда впоследствии он будет показан операцией чтения. Однако некоторые системы могут быть не в состоянии делать это; см. примечание к транзакционной целостности для обсуждения.

Сервер возвращает HTTP статус-код 201 Created и ДОЛЖЕН также вернуть заголовок Location, содержащий новые Logical Id и Version Id созданной версии ресурса:

  Location: [base]/[type]/[id]/_history/[vid]

где [id] и [vid] - это только что созданные id и version id версии ресурса. Серверы ДОЛЖНЫ возвращать заголовок ETag с versionId и заголовком Content-Location с ответом, который представляет собой полный версионный url (см. vread ниже) и заголовок Last-Modified.

Когда синтаксис ресурса или данных некорректен или недопустим и не может использоваться для создания нового ресурса, сервер возвращает HTTP статус-код 400 Bad Request. Когда сервер отклоняет содержимое ресурса из-за бизнес-правил, он возвращает HTTP статус-код 422 Unprocessible Entity error. В любом из случаев сервер ДОЛЖЕН вернуть тело ответа, содержащее OperationOutcome с подробными сообщениями об ошибках и описанием причины этих ошибок.

Распространенные HTTP коды состояния, возвращаемые в случае связанных с FHIR ошибок (в дополнение к обычным HTTP ошибкам, связанным с вопросами согласования безопасности, заголовков и типов контента):

  • 400 Bad Request - невозможно выполнить синтаксический разбор ресурса, либо он не проходит базовые правила валидации FHIR
  • 404 Not Found - не поддерживаемый тип ресурса, либо это не точка взаимодействия FHIR
  • 422 Unprocessable Entity - предложенный ресурс нарушает применимые профили FHIR или безнес-правила сервера. Ошибка может сопровождаться ресурсом OperationOutcome с дополнительной информацией

Примечание: серверы МОГУТ выбрать сохранять XML комментарии, команды обработки и форматирование или пробельные символы в JSON, когда принимают обновления, но не обязаны это делать. Возможно потребуется рассмотреть влияние этого на электронные цифровые подписи.

Для получения дополнительной информации по работе систем при обработке обновлений обратитесь к статье Create and Update Behavior.

Операция условного create позволяет клиенту создавать новый ресурс только в том случае, если некоторый эквивалентный ресурс ещё не существует на сервере. Клиент задает, что означает эквивалентность для данного случая с помощью поискового FHIR-запроса, используя стандартный заголовок расширения от HL7 - "If-None-Exist", как показано ниже:

  If-None-Exist: [search parameters]

Этот параметр просто содержит параметры поиска (которые будут в URL следовать за "?").

Когда сервер обрабатывает это обновление, он выполняет поиск, как указано, используя свои стандартные средства поиска по типу ресурса. Следующее действие сервера зависит от того, сколько совпадений было найдено:

  • Нет совпадений: Сервер выполняет create, как описано выше
  • Одно совпадение: Сервер игнорирует команду post и возвращает 200 OK
  • Несколько совпадений: Сервер возвращает ошибку 412 Precondition Failed, означающую, что критерии клиента не были достаточно селективными

Этот вариант может использоваться, чтобы избежать риска создания двумя клиентами ресурсов-дубликатов для одной и той же записи. Например клиент, отправляющий новый лабораторный результат, мог бы указать If-None-Exist: /Observation?identifier=http://my-lab-system|123 для гарантии, что он не создает запись-дубликат.

Отметьте, что транзакции и условные операции create/update/delete являются комплексными взаимодействиями, и не ожидается, что они будут реализованы всеми серверами. Серверы, которые не поддерживают условное обновление, должны возвращать HTTP-код ошибки 400 и результат операции OperationOutcome.

Эта операция ищет набор ресурсов на основе некоторого критерия фильтра. Это взаимодействие выполняется несколькими различными HTTP-командами. Чтобы искать сразу по всем ресурсам:

  GET [base]/[type]{?[parameters]{&_format=[mime-type]}}

Это поиск всех ресурсов определенного типа с использованием критериев, представленных в параметрах.

Из-за способа, которым некоторые пользовательские агенты и прокси обрабатывают запросы GET и POST, в дополнение к методу поиска на основе GET-запроса серверы, которые поддерживают search, ДОЛЖНЫ также поддерживать поиск на основе POST-запроса:

POST  [base]/[type]/_search{?[parameters]{&_format=[mime-type]}}

Запрос этого вида имеет точно такую же семантику, что и эквивалентная команда GET. Все эти взаимодействия поиска принимают ряд параметров, которые являются серией пар name'='value, закодированных в URL (или в виде application/x-www-form-urlencoded отправки POST). (См. W3C HTML forms ). Операции поиска обрабатываются, как определено в механизме обработки поиска.

Примечание: application/x-www-form-urlencoded поддерживается для команды POST, чтобы вызов поиска с помощью GET или POST можно было выполнять из HTML-форм в браузере (при этом может потребоваться существенное активное содержимое в браузере), хотя это и не является основным его применением.

Операции поиска обрабатываются так, как указано для механизма обработки поиска.

If the search succeeds, the server SHALL return a 200 OK HTTP status code and the return content SHALL be a Bundle with type = searchset containing the results of the search as a collection of zero or more resources in a defined order. The result collection can be long, so servers may use paging. If they do, they SHALL use the method described below (adapted from RFC 5005 (Feed Paging and Archiving ) for breaking the collection into pages if appropriate. The server MAY also return an OperationOutcome resource within the searchset Bundle entries that contains additional information about the search; if one is sent it SHALL NOT include any issues with a fatal or error severity, and it SHALL be marked with a Bundle.entry.search.mode of outcome.

Если поиск не удается выполнить, возвращается код состояния вида 4xx или 5xx наряду с ресурсом OperationOutcome.

Common HTTP Status codes returned on FHIR-related errors (in addition to normal HTTP errors related to security, header and content type negotiation issues):

  • 400 Bad Request - search could not be processed or failed basic FHIR validation rules
  • 401 Not Authorized - authorization is required for the interaction that was attempted
  • 404 Not Found - resource type not supported, or not a FHIR end-point

Для поиска логического модуля (compartment) для всех возможных ресурсов либо только определённого типа, соответственно:

  GET [base]/[Compartment]/[id]/{*?[parameters]{&_format=[mime-type]}}
  GET [base]/[Compartment]/[id]/[type]{?[parameters]{&_format=[mime-type]}}

Например чтобы получить все ресурсы observation для конкретного LOINC-кода, связанного с конкретным случаем обслуживания:

  GET [base]/Encounter/23423445/Observation?code=2951-2  {&_format=[mime-type]}

Обратите внимание, что есть еще специфические операции, предусмотренные для поддержки выборки полной записи пациента или всех записей для encounter.

Также можно искать сразу по нескольким типам ресурсов:

  GET [base]?_type=Condition,Observation&[parameters]{&_format=[mime-type]}

This is a request to search on both Condition and Observation. In this case, the only parameters that can be used are those defined for both Condition and Observation (using SearchParameter.base - see Cross-resource Search Parameters), or the parameters defined for all resources. If a search lists types not listed SearchParameter.base for any of the parameters, this is an error, and a server SHOULD return a 400 status. It's also possible to search on all types at once:

  GET [base]?[parameters]{&_format=[mime-type]}

При поиске сразу всех ресурсов можно использовать только общие для всех ресурсов параметры.

The capabilities interaction retrieves the server's Capability Statement that defines how it supports resources. The interaction is performed by an HTTP GET command as shown:

  GET [base]/metadata {?_format=[mime-type]}

In addition, there is another method to get the capability statement, using the HTTP OPTIONS command:

  OPTIONS [base] {?_format=[mime-type]}

However as of STU3, this method is deprecated, and will be removed in a future version. Using OPTIONS like this is not conformant with HTTP, and creates challenges for cross-origin resource sharing support.

Applications SHALL return a Capability Statement that specifies which resource types and interactions are supported for the GET command. If a 404 Unknown is returned from the GET, FHIR is not supported on the nominated service url. An ETag header SHOULD be returned with the CapabilityStatement. The value of the header SHALL change if the CapabilityStatement itself changes. Additional parameters that are required to be returned with the OPTIONS command are defined in the OMG hData RESTful Transport specification.

The Capability statement returned typically has an arbitrary id, and no meta element, though it is not prohibited. Capability statements can become quite large; Servers are encouraged to support the _summary and _elements parameters on the capabilities interaction, though this is not required. In addition, servers are encouraged to implement the $subset and $implements operations to make it easy for a client to check conformance.

In addition to this capabilities interaction, a server may also choose to provide the standard set of interactions (read, search, create, update) defined on this page for the CapabilityStatement Resource end-point. This is different from the capabilities interaction:

capabilities interactionreturns a capability statement describing the server's current operational functionality
CapabilityStatement end-pointmanages a repository of capability statements (e.g. the HL7 capability statement registry)

All servers are required to support the capabilities interaction, but servers may choose whether they wish to support the CapabilityStatement end-point, just like any other end-point.

Implementation Note: In DSTU 2 and earlier, the resource that this interaction returned was named "Conformance". Clients often connect to a server, and use the capabilities interaction to check whether they are version and/or feature compatible with the server. Such clients should be able to process either a Conformance or a CapabilityStatement resource.

Взаимодействие transaction отправляет на сервер набор действий, чтобы выполнить их одним атомарным действием. Можно отправлять несколько действий над несколькими ресурсами одного или различных типов, это может быть сочетание разных операций, определенных на этой странице (например read, search, create, update, delete и т. п.).

Особенно это полезно, когда иначе потребовалось бы множество взаимодействий с возможным риском потери ссылочной целостности, если бы последующие взаимодействия не удались (например при сохранении ресурса Provenance и его соответствующего целевого ресурса, или ввод индекса документа и сопровождающего его документа в репозиториях документов).

Отметьте, что транзакции и условные операции create/update/delete являются комплексными взаимодействиями, и не ожидается, что они будут реализованы всеми серверами.

Операции batch и transaction выполняются HTTP-командой POST, как показано ниже:

  POST [base] {?_format=[mime-type]}

Содержимое тела post-запроса - это Bundle с Bundle.type = batch или transaction. Каждый элемент entry содержит элемент transaction (Bundle.entry.transaction) , в котором указываются HTTP-детали операции для того, чтобы проинформировать систему, обрабатывающую транзакцию, о том, что необходимо сделать с каждым entry (примечание: request является необязательным, однако ДОЛЖЕН присутствовать). Если указана HTTP-операция PUT или POST, тогда entry ДОЛЖНА содержать ресурс, выступающий телом операции. как будто это отдельные операции, описанные на этой странице или для Extended Operations. Эти операции подлежат обычной обработке для каждого, включая элемент meta, верификацию и версионные обновления, а также транзакционную целостность).

Примеры:

Для типа batch в Bundle НЕ ДОЛЖНО быть взаимных зависимостей между различными записями (entries), которые вызывают измененеие на сервере. Успех или неудача одного изменения НЕ ДОЛЖНЫ влиять на успех, неудачу или полученное в результате выполнения содержимое другого изменения. Серверы ДОЛЖНЫ подтверждать, что это именно так. Отметьте, что считается, что серверы выполняют пакетную обработку в том же порядке, как указано ниже для транзакций, хотя порядок выполнения не должен иметь значения, учитывая предыдущее правило.

Static references within a Bundle.entry.resource to another Bundle.entry.resource that is being created within the batch are considered to be non-conformant.

Для transaction серверы ДОЛЖНЫ либо принять все действия и вернуть HTTP-код 200 OK наряду с бандлом-ответом (см. ниже), либо отклонить все ресурсы и вернуть HTTP-тип ответа 400 или 500. Не будет ошибкой, если поданный бандл не содержит в себе ресурсов. Результат обработки транзакции НЕ ДОЛЖЕН зависеть от порядка ресурсов в этой транзакции. Ресурс может появляться в транзакции только один раз (по идентичности).

Из-за правила, что транзакция является атомарной операцией, в которой все действия либо проходят, либо падают, и порядок записей не имеет значения, имеется определённый порядок обработки этих действий:

  1. Обработать все операции DELETE
  2. Обработать все операции POST
  3. Обработать все операции PUT
  4. Обработать все операции GET

Если какие-либо идентификаторы ресурсов (в том числе установленные идентификаторы из условного обновления/удаления) перекрываются в этапах 1-3, то транзакция ДОЛЖНА упасть (не выполниться).

Примечание к STU: клиенты могут запрашивать выполнение операций в рамках транзакции. Некоторые транзакции могут вызывать побочные эффекты, например создание новых ресурсов или другие действия, которые может быть трудно вписать в фреймворк транзакции. Мы ожидаем входных данных касательно этой проблемы во время периода STU.

Страничка для размещения ваших отзывов .

Транзакция может содержать ссылки из одного ресурса на другой в бандле, включая циклические ссылки, где ресурсы ссылаются друг на друга. Если сервер назначает новый идентификатор какому-то ресурсу в комплекте в рамках правил обработки, описанных выше, он ДОЛЖЕН также обновить все ссылки на этот ресурс в этом же бандле, когда они будут обрабатываться. Ссылки на ресурсы, не являющиеся частью этого комплекта, остаются нетронутыми. Ссылки на конкретные версии должны остаться ссылками на конкретные версии после обновления ссылок. Серверы ДОЛЖНЫ заменить все соответствующие ссылки в бандле, включая идентификаторы ресурсов, ссылки на ресурсы, URL-элементы и атрибуты тегов <a href="" & <img src="" в описательной части.

При обработке команды "POST" (create) полный URL рассматривается в качестве идентификатора (id) ресурса в источнике и игнорируется; сервер генерирует идентификатор id для этого ресурса. Для операций обновления сервер выполняет мэппинг между указанным fullUrl и локальным URL, под которым серверу известен этот экземпляр, если это представляется возможным. Если у сервера нет соответствия для fullUrl, то сервер игнорирует базовый URL и пытается выполнить обновление, полагая, что базовый адрес совпадает с базовым адресом сервера. Это позволяет отправлять один и тот же бандл-транзакцию в несколько систем без необходимости изменения fullUrl для каждого адресата.

При обработке пакета или транзакции сервер МОЖЕТ по желанию учитывать существующие локальные идентификаторы (например Observation/1234 остаётся Observation/1234 на сервере), однако поскольку это безопасно только в регулируемых обстоятельствах, серверы по желанию могут присваивать новые идентификаторы всем подаваемым ресурсам независимо от любых заявленных логических id в ресурсе или fullUrl в записях в пакете/транзакции.

Примечание: эта модель поведения подлежит проверке на основе опыта реализации и может меняться.

Provide feedback here .

Conditional References

When constructing the bundle, the client may not know the logical id of a resource, but it may know identifying information - e.g. an identifier. This situations arises commonly when building transactions from v2 messages. The client could resolve that identifier to a logical id using a search, but that would mean that the resolution to a logical id does not occur within the same transaction as the commit (as well as significantly complicating the client). Because of this, in a transaction (and only in a transaction), references to resources may be replaced by a search URI that describes how to find the correct reference:

 <Bundle xmlns="http://hl7.org/fhir">
   <id value="20160113160203" />
   <type value="transaction" />
   <entry>
     <fullUrl value="urn:uuid:c72aa430-2ddc-456e-7a09-dea8264671d8" />
     <resource>
       <Observation>
         <subject>
            <reference value="Patient?identifier=12345"/>
         </subject>
         <--! rest of resource omitted -->
       </Observation>
     </resource>
     <request>
       <method value="POST" />
     </request>
   </entry>
 <Bundle>

The search URI is relative to the servers [base] path, and always starts with a resource type: [type]:?parameters.... Only filtering parameters are allowed; none of the parameters that control the return of resources are relevant.

When processing transactions, servers SHALL:

  • check all references for search URIs
  • For search URIs, use the search to locate matching resources
  • if there are no matches, or multiple matches, the transaction fails, and an error is returned to the user
  • if there is a single match, the server replaces the search URI with a reference to the matching resource

Для пакета (batch) или успешной транзакции сервер в качестве ответа ДОЛЖЕН вернуть Bundle с типом batch-response или transaction-response, который содержит по одной записи для каждой записи в запросе в том же самом порядке с результатом обработки этой записи. Для неудавшейся транзакции сервер возвращает один OperationOutcome вместо Bundle.

Клиент может использовать возвращённый бандл для отслеживания результатов обработки записи и идентификаторов, присвоенных ресурсам сервером. Каждый элемент entry ДОЛЖЕН содержать элемент transactionResponse, который детализирует результат обработки этой записи - HTTP статус-код и значения заголовков location и ETag, которые используются для идентификации и версионирования ресурсов. Кроме того, в entry может быть включен ресурс.

Сервер может принимать и другие типы бандлов помимо transaction в качестве транзакций.

Bundles типа history имеют такую же внутреннюю структуру, что и транзакция, и могут обрабатываться как она, поэтому серверы ДОЛЖНЫ принимать bundle типа history - это дает возможность без труда копировать данные с одного сервера на другой. Однако обратите внимание, что существующие ограничения транзакций не применяются к history list, и ресурс может появиться в нем больше одного раза, поэтому у серверов, обрабатывающих bundles типа history, должна быть какая-то стратегия для управления такими случаями.

У других типов bundle, если сервер решает принимать их, не будет элемента transaction (отметьте, что в каждом entry будет ресурс). В этом случае сервер обрабатывает entry либо операцией create, либо update в зависимости от того, идентифицирует ли он ресурс - если идентификация ресурса относится к допустимому адресу на сервере, он должен трактовать это как обновление по этому адресу. Примечание: эта опция позволяет клиенту делегировать серверу процесс нахождения соответствия.

Взаимодействие history извлекает историю либо конкретного ресурса, либо всех ресурсов данного типа, либо всех ресурсов, поддерживаемых системой. Эти три варианта взаимодействия history выполняются HTTP-командой GET, как показано ниже:

  GET [base]/[type]/[id]/_history{?[parameters]&_format=[mime-type]}
  GET [base]/[type]/_history{?[parameters]&_format=[mime-type]}
  GET [base]/_history{?[parameters]&_format=[mime-type]}

Возвращаемым содержимым будет Bundle с типом history, содержащий указанную историю версий, упорядоченную таким образом, что самые старые версии идут последними, и включающий удалённые ресурсы. Каждая запись ДОЛЖНА содержать как минимум resource, в котором лежит ресурс, полученный в результате этой операции, либо request с entry.request.method. request предоставляет информацию о произведённой операции, которая привела к созданию новой версии, и позволяет, к примеру, системе-подписчику различать операции create и update. Основная причина, по которой resource может отсутствовать, состоит в том, что ресурс был изменён каким-то другим каналом, а не через RESTful-интерфейс. Если в entry.request.method указан метод PUT или POST, то такая запись ДОЛЖНА содержать ресурс.

Операции create, update и delete создают записи в истории. Другие операции - нет (обратите внимание, что эти операции могут создавать побочные эффекты, такие как новые ресурсы AuditEvent; они представляются в виде операций create сами по себе). Новые ресурсы или обновления существующих ресурсов, вызываемые операциями, также появляются в истории, как и обнволения ресурсов, которые являются результатом операций вне области действия RESTful-интерфейса.

Операция create представляется в истории операций следующим образом:

  <entry>
    <resource>
      <Patient>
        <!-- the id of the created resource -->
        <id value="23424"/>
        <!-- snip -->
      </Patient>
    </resource>
    <request>
      <!-- POST: this was a create -->
      <method value="POST"/>
      <url value="Patient"/>
    </request>
  </entry>

Обратите внимание, что условное создание, обновление и удаление конвертируются в прямые обновления и удаления в истории операций.

Кроме стандартного параметра _format, параметры этого взаимодействия могут также включать:

_count : integersingleТребуемое количество возвращаемых записей. Сервер не обязан вернуть именно столько записей, но не может вернуть большее количество
_since : instantsingleВключить только те версии ресурсов, которые были созданы в или после указанного времени
_at : dateTimesingle Включить только те версии ресурсов, которые были текущими в некоторый момент времени в течение периода, указанного в значении даты/времени (периодов может быть больше одного)

Список истории можно ограничить некоторым периодом с помощью параметра _since, который содержит полную дату/время с указанием часового пояса. Клиенты должны понимать, что из-за неточности времени они могут получать уведомления об обновлении ресурсов on the boundary instant больше одного раза. Серверы не обязаны поддерживать точность выше, чем 1 секунда.

Список обновлений может быть длинным, поэтому серверы могут использовать разбиение на страницы (пагинацию). Если они делают это, они ДОЛЖНЫ использовать метод, описанный ниже, для разбиения списка на страницы, где это необходимо, и поддерживать указанный _count на всех страницах.

Взаимодействие history может использоваться для установки подписки одной системы на другую в целях синхронизации ресурсов между ними. Другие средства синхронизации систем можно посмотреть в статье Subscription resource.

Дополнительные примечания, касающиеся поддержки истории ресурсов:

  • history - это история версий записей на поресурсной основе. Она не предназначена для поддержки параллельных (совпадающих, concurrent) версий или разветвлённой истории версий
  • Таким образом нет способа обновить или удалить предыдущие версии записи за исключением того, что можно изменить метаданные (в основном в целях контроля доступа)
  • Все предыдущие версии ресурса считаются заменёнными (замещёнными новой версией) и больше не являются активными, однако сохраняются в целях аудита/обеспечения целостности
  • В случае, когда предыдущая версия ресурса должна быть явно задокументирована как введённая по ошибке ('entered-in-error'), используйте ресурс Provenance, указывающий на эту предыдущую версию ресурса
  • При отслеживании истории конкретного ресурса, приложениям следует извлекать все ресурсы Provenance, связанные с этим ресурсом или его предыдущими версиями
  • If a request is made for a history that is not available (e.g. the system does not keep a history for the type, or the particular instance), the server should return a 404 Not Found along with an OperationOutcome explaining the problem

При обработке операций create и update FHIR-сервер не обязан принимать ресурс целиком как есть; когда ресурс извлекается с помощью операции read впоследствии, ресурс может быть другим. Разница может возникнуть по нескольким причинам:

  • Сервер объединил обновленное содержимое с существующим
  • Сервер применил бизнес-правила и изменил содержимое
  • Сервер не полностью поддерживает все свойства или возможные значения ресурса

Обратите внимание, что нет метода общего назначения сделать слияние с существующим содержимым или изменение содержимого в соответствии с бизнес-правилами безопасным или предсказуемым, а те, что доступны, надежны и/или необходимы - в значительной степени зависят от контекста. Такого рода поведение может быть вызвано соображениями безопасности. Что касается неполной поддержки, клиенты могут обратиться к ссылкам на профили в базовом CapabilityStatement сервера, чтобы определить, какие свойства или значения сервер не поддерживает.

По мере того, как сервер изменяет ресурс под любой из перечисленных выше причин, FHIR-сервер будет создавать последствия реализации для экосистемы, частью которой он является, которыми будет необходимо управлять (т. е. это будет обходиться дороже). По этой причине серверам СЛЕДУЕТ менять ресурс как можно меньше. Однако из-за изменчивости, которая существует в здравоохранении, данная спецификация допускает, что серверы МОГУТ изменять ресурс при создании/обновлении.

Аналогичным образом, по мере того как контекст реализации привносит особые правила слияния контента или изменения содержания, контекст становится всё более дорогими в обслуживании.

Хотя эти правила изложены для серверов, подобная концепция применяется и к клиентам - в связи с тем, что различные клиентские системы, взаимодействующие с этим сервером, не поддерживают один и тот же набор характеристик, клиенты и/или этот сервер будут вынуждены применять специальную логику для предотвращения потери или повреждения информации.

Некоторые из этих трудностей можно уменьшить, следуя схеме, построенной на версионных обновлениях. В этой схеме:

  • Сервер предоставляет операцию чтения read interaction for any resource it accepts update interactions on
  • Перед обновлением клиент reads the latest version of the resource
  • Клиент применяет к ресурсу желаемые изменения, оставляя другую информацию нетронутой (обратите внимание на extension related rules around this)
  • Клиент записывает результат с помощью операции update interaction, and is able to handle a 409 or 412 response (usually by trying again)

Если клиенты придерживаются этой схемы, то информация из других систем, которую они не понимают, будет сохраняться на протяжении этого обновления.

Обратите внимание, что у сервера есть возможность хранить информацию, которая была бы потеряна, но у сервера нет способа определить, опустил ли клиент эту информацию, потому что она не поддерживалась (возможно в этом случае) или он хотел удалить эту информацию.

И клиентским, и серверным системам СЛЕДУЕТ четко документировать, каким образом обеспечивается целостность транзакции.

Примечание к STU : На данный момент единственный способ документировать, каким образом обеспечивается целостность транзакций - это текст в описательной части ресурса CapabilityStatement. Будем благодарны за ваши отзывы во время периода пробного использования по вопросу, какие из этих данных должны быть вычисляемыми (если вообще должны).

Страничка для размещения ваших отзывов .

Если серверы предоставляют разбиение результатов взаимодействий search или history на страницы, они ДОЛЖНЫ соответствовать этому методу (адаптированному из RFC 5005 (Feed Paging and Archiving) , для отправки ссылок продолжения клиенту при возвращении Bundle (например для истории и поиска). Если сервер не делает этого, нет никакого способа продолжать навигацию по страницам.

Данный пример показывает третью страницу результатов поиска:

<Bundle xmlns="http://hl7.org/fhir">
  <!-- snip metadata -->
  <!-- This Search url starts with base search, and adds the effective
    parameters, and additional parameters for search state. All searches
    SHALL return this value.

	  In this case, the search continuation method is that the server
    maintains a state, with page references into the stateful list.
	-->
  <link>
    <relation value="self">
    <url value="http://example.org/Patient?name=peter&stateid=23&page=3"/>
  </link>
  <!-- 4 links for navigation in the search. All of these are optional, but recommended -->

  <link>
    <relation value="first"/>
    <url value="http://example.org/Patient?name=peter&stateid=23&page=1"/>
  </link>
  <link>
    <relation value="previous"/>
    <url value="http://example.org/Patient?name=peter&stateid=23&page=2"/>
  </link>
  <link>
    <relation value="next"/>
    <url value="http://example.org/Patient?name=peter&stateid=23&page=4"/>
  </link>
  <link>
    <relation value="last"/>
    <url value="http://example.org/Patient?name=peter&stateid=23&page=26"/>
  </link>

  <!-- then the search results... -->
</Bundle>

Серверу нет необходимости использовать динамический способ подкачки, как показано в этом примере - это остается на усмотрение сервера, как лучше всего обеспечить, чтобы продолжение сохраняло целостность в контексте текущих изменений в ресурсах. Альтернативный подход заключается в использовании ссылок на конкретные версии записей на границах, но он подвержен сбоям непрерывности при обновлении записей.

A server MAY add additional state tracking parameters to the links, as shown in the example above. The client must use the server supplied links in order to traverse the pages. Сервер МОЖЕТ сообщить клиенту общее количество ресурсов, возвращаемых этим взаимодействием, для которого результаты разбиваются на страницы, с помощью Bundle.total.

Обратите внимание, что при поиске, где можно использовать _include для возвращения дополнительных связанных ресурсов, общее число ресурсов в фиде может превышать число, указанное в totalResults.

Протокол HTTP может быть направлен через HTTP-прокси, например squid. Подобные прокси прозрачны для приложений, хотя реализаторы должны быть готовы к последствиям кеширования, особенно к риску получения устаревшего содержимого. См. более подробную информацию в спецификации HTTP .

Механизмы интерфейса могут также размещаться между потребителем и провайдером. Они отличаются от прокси тем, что активно изменяют содержимое и/или назначение HTTP-обмена и не связаны правилами, которые применяются к HTTP-прокси. Такие агенты разрешены, но ДОЛЖНЫ помечать HTTP-заголовки для оказания помощи в устранении неполадок.

Любой агент, модифицирующий HTTP-запрос или содержимое ответа не в рамках правил для HTTP прокси, ДОЛЖЕН добавить штамп в HTTP-заголовки, подобный этому:

  request-modified-[identity]: [purpose]
  response-modified-[identity]: [purpose]

Этот идентификатор ДОЛЖЕН быть отдельным токеном, определенным администратором агента, который будет достаточно идентифицировать этого агента в контексте использования. Заголовок ДОЛЖЕН указывать цель модификации содержимого агентом. Оконечные системы НЕ ДОЛЖНЫ использовать этот заголовок ни для каких целей. Он предназначен для помощи в решении проблем с системой.

Данная RESTful-спецификация, описываемая здесь, основана на спецификации OMG Health RESTful specification (HData) . В этом отношении FHIR действует в качестве Record Format Profile, как описано в той спецификации. Следует учитывать следующие существенные факторы:

  • FHIR устанавливает соответствие между hData-разделами и типами ресурсов, и hData-документами и экземплярами ресурсов. Подразделы отсутствуют, а клиентские системы не могут создавать новые секции, хотя compartments ведут себя в некоторой степени наподобие разделов
  • Так как клиенты не могут создавать новые секции (POST на URL сервиса), POST на URL сервиса использован для взаимодействия transaction (различие проходит проверку)
  • FHIR не определяет (пока что) корневой документ. Когда определен, он будет содержать информацию о том, что FHIR-сервер сделал (в противоположность заявлению о соответствии, которое описывает, что он может сделать)
  • Обратите внимание, что данная спецификация не приводит повторно правила из hData RESTful Transport, относящиеся к команде OPTIONS в URL сервиса, однако эти правила (дополнительные заголовки и пр.) по-прежнему применяются
  • FHIR does not (yet) define a root document. When defined, it will contain information about what the FHIR server has done (as opposed to a Capability Statement, which describes what it is capable of doing)
  • Note that this specification does support the hData RESTful Transport OPTIONS command on the service URL

Таблицы ниже представляют собой сводку всех описанных здесь взаимодействий. Обратите внимание, что все запросы могут включать необязательный Accept-заголовок для указания формата, используемого для ответа (это справедливо даже в отношении DELETE, так как может быть возвращен OperationOutcome).

Interaction PathRequest
Verb Content-Type Body Prefer Conditional
read /[type]/[id] GET N/A N/A N/A O: ETag, If-Modified-Since, If-None-Match
vread /[type]/[id]/_history/[vid] GET N/A N/A N/A N/A
update /[type]/[id] PUT R Resource O O: If-Match
delete /[type]/[id] DELETE N/A N/A N/A N/A
create /[type] POST R Resource O O: If-None-Exist
search /[type]? GET N/A N/A N/A N/A
/[type]/_search? POST application/x-www-form-urlencoded form data N/A N/A
search-all ? GET N/A N/A N/A N/A
capabilities /metadata GET N/A N/A N/A N/A
transaction / POST R Bundle O N/A
history /[type]/[id]/_history GET N/A N/A N/A N/A
history-type /[type]/_history GET N/A N/A N/A N/A
history-all /_history GET N/A N/A N/A N/A
(operation) /$[name], /[type]/$[name] or /[type]/[id]/$[name] POST R ParametersN/A N/A
GET N/A N/A N/A N/A
POST application/x-www-form-urlencoded form data N/A N/A

Примечания:

  • N/A = не представлен (not present), R = обязательный (Required), O = необязательный (optional)
  • Операции, определенные для всех ресурсов, включая прямой доступ к элементу meta, см. в Resource Operations
InteractionResponse
Content-Type Body Location Versioning Status Codes
read R R: Resource N/A R: ETag, Last-Modified 200, 404, 410
vread R R: Resource N/A R: ETag, Last-Modified 200, 404
update R if body O: Resource (Prefer) R on create R: ETag, Last-Modified 200, 201, 400, 404, 405, 409, 412, 422
delete R if bodyO: OperationOutcome N/A N/A 200, 204, 404, 405, 409, 412
create R if body O : Resource (Prefer) R R: ETag, Last-Modified 201, 400, 404, 405, 422
search R R: Bundle N/A N/A 200, 401?
search-all R R: Bundle N/A N/A 200, 401?
capabilities R R: CapabilityStatementN/A N/A 200, 404
transaction R R: Bundle N/A N/A 200, 400, 404, 405, 409, 412, 422
history R R: Bundle N/A N/A 200
history-type R R: Bundle N/A N/A 200
history-all R R: Bundle N/A N/A 200
(operation) R R: Parameters/ResourceN/A N/A 200

Примечание: в этой таблице перечислены все упомянутые коды состояния, но возможно использование и других кодов состояния в соответствии с HTTP-спецификацией. Дополнительными кодами будут, скорее всего, ошибки сервера и различные коды, связанные с протоколами аутентификации.