火 事 кадзи: (сущ) огонь; пожар

Kaji - это универсальное хранилище клинических данных (CDR), реализующее большую часть спецификации FHIR STU3. Он отличается от других реализаций в пространстве по-разному:

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

Мы развернули экземпляр песочницы по адресу https://kaji.healthforge.io, чтобы позволить общественности поэкспериментировать с сервером и запустить на нем набор тестов Crucible. Мы также поместили контейнер Docker в Docker Hub (лицензия MIT) для всех, кто хочет развернуть свой собственный экземпляр.

Стек технологий

Требование к серверу заключалось в том, что он должен работать на JVM, и это повлияло на некоторые другие решения относительно стека.

HAPI

HAPI FHIR - это эталонная реализация стандарта на языке Java, поэтому было бы разумно начать здесь, но не обошлось и без проблем, описанных ниже. Мы используем его модель данных FHIR, возможности маршалинга и проверки, но не используем его интерфейсную часть REST или внутреннюю поддержку JPA.

Scala / Finagle

Finagle - это высокопроизводительный сетевой фреймворк, созданный Twitter на основе популярной библиотеки асинхронного ввода-вывода netty. Он написан на Scala, но предоставляет API-интерфейсы для использования из Java или Scala. Мы предпочитаем Scala как язык, в основном из-за пониженной многословности и отличной поддержки конструкций функционального программирования.

PostgreSQL

PostgreSQL, как (точно) описывают его разработчики, является самой продвинутой базой данных с открытым исходным кодом в мире. В ее основе лежит реляционная модель, но разработчики не уклоняются от предоставления функций базы данных объектов или документов там, где они могут быть полезны. PostgreSQL особенно подходит в качестве бэкэнда для сервера FHIR. Это можно отнести ко многим его продвинутым функциям, но особенно выделяется jsonb. Я лично не поклонник JSON-кодирования ресурсов FHIR - он включает в себя некоторые уродливые клуджи, которые противоречат базовой модели данных, ориентированной на XML, - но мощности jsonb достаточно, чтобы перевесить эти опасения, и поэтому мы используем его в качестве своего основной формат хранения. Поддержка индекса GIN чрезвычайно полезна и позволяет нам оптимизировать широкий спектр запросов FHIR из коробки.

Развертывание

Мы развертываем Kaji как док-контейнер на основе стандартной базы openjdk. Текущие производственные развертывания основаны на Amazon ECS с использованием серверной части RDS и Google Kubernetes Engine с использованием серверной части Cloud SQL.

Мы пришли к выводу, что Kubernetes предпочтительнее ECS по ряду причин, но сервис Amazon EKS не был доступен при первом развертывании.

Вызовы

HAPI

HAPI (как библиотека модели данных) не обязательно является идеальным строительным блоком для FHIR-сервера общего назначения. В качестве эталонной реализации требуется, чтобы он отвечал всем возможным требованиям, и, как следствие, поставляется с изрядным объемом багажа, который нам не нужен. Сервер общего назначения не очень интересуется спецификой отдельных ресурсов (за исключением, возможно, некоторых специализированных случаев, таких как записи аудита), поэтому не особенно полезно иметь отдельные классы Java для каждого из них (не говоря уже о том, что что изменяемые классы с геттерами и сеттерами действительно не подходят нашему стилю разработки scala). Что действительно необходимо, так это библиотека, реализующая базовую модель данных FHIR, дополненную функциями для маршалинга, проверки и т. Д. На более низком уровне.

Скала

Компилятор scala, как известно, работает медленно (он выполняет около 25 проходов по ​​коду), особенно при интенсивном использовании таких функций, как имплициты и макросы. Кодовая база может быть адаптирована для некоторого улучшения ситуации, но это само по себе требует значительных усилий для уменьшения отдачи. IDE Scala обычно медлительны по той же причине. Лично я справляюсь с этим, работая на машинах с новейшими ядрами i7 и 64 ГБ ОЗУ, но мои коллеги настаивают на использовании MacBook и в результате страдают.

Finagle

Finagle - это RPC-фреймворк промышленного уровня, который предоставляет иногда обманчиво простые абстракции по сравнению со сложностью и мощью как его внутренних компонентов, так и внутренней библиотеки netty. Это делает его легко доступным для новых пользователей, но абстракции имеют тенденцию к утечкам, и в конечном итоге возникает необходимость копать глубже. Например, рассмотрим клиентский стек по умолчанию:

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

Когда что-то идет не так с Finagle (а мы наблюдаем некоторые странные взаимодействия с другим низкоуровневым сетевым программным обеспечением, таким как ELB от Amazon), отладка может быть затруднена. Сообщения об ошибках часто бесполезны, и вам нужен как доступ, так и глубокое понимание огромного количества показателей, которые предоставляет фреймворк.

PostgreSQL

Распространенная жалоба на postgres заключается в том, что его не так просто масштабировать по горизонтали, как недавно разработанные распределенные базы данных. Можно было бы реализовать ручное шардирование базы данных в Кадзи. Учитывая доступность вертикального масштабирования (например, AWS предлагает огромные серверы RDS, такие как db.x1e.32xlarge), я не думаю, что это особенно высокий приоритет.

Пример использования: Vision Coach

Vision Coach - это новая цифровая платформа для ведения пациентов с диабетическим макулярным отеком. Подробное описание вы можете прочитать здесь. Короче говоря, платформа состоит из мобильного приложения для пациентов с диабетическим макулярным отеком (DME, форма диабетического заболевания глаз), созданного с использованием React Native для iOS и Android, и веб-приложения для офтальмологов, ведущих пациентов с DME, созданного с помощью React. Основные компоненты представлены на Рисунке 2.

Мы использовали подход FHIR-first к разработке модели данных Vision Coach. Поскольку совместимость в той или иной форме является почти неизбежным требованием для любого медицинского приложения - например, интеграция с другими приложениями и инструментами или даже соблюдение юридических требований, таких как право GDPR на переносимость данных, - мы считаем такой подход оправданным. В случае Vision Coach очевидным ранним проявлением этого требования была необходимость избегать дублирования ввода данных, на что у занятых врачей просто нет времени.

Принуждение к согласованию вашей модели с совместимым стандартом с самого начала может сэкономить много усилий в будущем, когда эти требования будут выполнены. Это не панацея: FHIR - это просто стандарт платформы, и вполне может потребоваться некоторая картографическая работа для соответствия целевому профилю, но это хорошая отправная точка. Альтернативой является настраиваемая база данных, разработанная исключительно для удовлетворения (начальных) требований приложения. Это, конечно, намного быстрее, но это недальновидно не только по причинам совместимости, но и потому, что требования могут меняться и меняются. Конечно, вы можете переносить модель данных по мере появления новых требований, но использование CDR общего назначения, например Kaji, с самого начала устраняет эту потребность во многих важных аспектах. Также стоит отметить, что (особенно для новичков в сфере здравоохранения) FHIR предоставляет базовую модель данных, которая, скорее всего, будет больше соответствовать существующей практике, чем что-то составленное с чистого листа.

На рисунке 3. показано, как модель данных Vision Coach отображается на выборку ресурсов FHIR.

Как видите, не существует сопоставления 1: 1 между сущностями с точки зрения пользовательского интерфейса и ресурсами в базе данных FHIR. Я думаю, что это, вероятно, обычная проблема в приложениях с поддержкой FHIR, и это еще одна веская причина для разработки маппинга заранее.

Будущая работа

Есть три очевидных направления дальнейшей работы над проектом:

FHIR R4

Кадзи в настоящее время внедряет FHIR STU3. Определенно имеет смысл добавить поддержку R4, которая является текущей версией стандарта и включает нормативное содержание.

Отсутствующие функции

FHIR - это большой стандарт, который обычно не предназначен для полной реализации вне эталонных реализаций. Нам не хватает нескольких общих областей, которые были бы полезны, например транзакций.

За пределами базового стандарта

Существуют различные расширения, профили и дополнения к базовому стандарту, которые было бы полезно реализовать. Например: SMART на FHIR, различные стандарты IHE, Сбор структурированных данных и GraphQL. Также может быть полезно предоставить доступ к тем же основным клиническим данным, используя стандарты, не относящиеся к FHIR, такие как DICOMweb, CTS2, LDAP / IHE HPD и OpenEHR.

Следите за обновлениями и выпусками в течение 2019 года.