FHIR Motor Kitaplığı'nı kullanarak FHIR kaynaklarını yönetme

1. Başlamadan önce

Ne oluşturacaksınız?

Bu codelab'de, FHIR Engine kitaplığını kullanarak bir Android uygulaması oluşturacaksınız. Uygulamanız, FHIR kaynaklarını bir FHIR sunucusundan indirmek ve yerel değişiklikleri sunucuya yüklemek için FHIR Engine Kitaplığı'nı kullanır.

Neler öğreneceksiniz?

  • Docker kullanarak yerel bir HAPI FHIR sunucusu oluşturma
  • FHIR Engine Kitaplığı'nı Android uygulamanıza entegre etme
  • FHIR kaynaklarını indirmek ve yüklemek için tek seferlik veya düzenli bir iş ayarlamak üzere Sync API'yi kullanma
  • Arama API'sini kullanma
  • FHIR kaynaklarını yerel olarak oluşturmak, okumak, güncellemek ve silmek için Veri Erişimi API'lerini kullanma

İhtiyacınız olanlar

Daha önce Android uygulaması geliştirmediyseniz ilk uygulamanızı oluşturarak başlayabilirsiniz.

2. Test verileriyle yerel bir HAPI FHIR sunucusu oluşturma

HAPI FHIR, popüler bir açık kaynak FHIR sunucusudur. Android uygulaması için codelab'imizde bağlanılacak yerel bir HAPI FHIR sunucusu kullanıyoruz.

Yerel HAPI FHIR sunucusunu ayarlama

  1. HAPI FHIR'ın en son görüntüsünü almak için terminalde aşağıdaki komutu çalıştırın.
    docker pull hapiproject/hapi:latest
    
  2. Daha önce indirilen görüntüyü çalıştırmak için Docker Desktop'ı kullanarak hapiproject/hapi veya aşağıdaki komutu çalıştırarak HAPI FHIR container'ı oluşturun.
    docker run -p 8080:8080 hapiproject/hapi:latest
    
    Daha fazla bilgi edinin.
  3. URL'yi http://localhost:8080/ bir tarayıcıda açarak sunucuyu inceleyin. HAPI FHIR web arayüzünü görmeniz gerekir.HAPI FHIR web arayüzü

Yerel HAPI FHIR sunucusunu test verileriyle doldurma

Uygulamamızı test etmek için sunucuda bazı test verilerine ihtiyacımız var. Synthea tarafından oluşturulan sentetik verileri kullanacağız.

  1. Öncelikle synthea-samples'dan örnek verileri indirmemiz gerekir. synthea_sample_data_fhir_r4_sep2019.zip dosyasını indirip çıkarın. Sıkıştırılmamış örnek verilerde, her biri ayrı bir hasta için işlem paketi olan çok sayıda .json dosyası bulunur.
  2. Üç hasta için test verilerini yerel HAPI FHIR sunucusuna yükleyeceğiz. JSON dosyalarını içeren dizinde aşağıdaki komutu çalıştırın.
    curl -X POST -H "Content-Type: application/json" -d @./Aaron697_Brekke496_2fa15bc7-8866-461a-9000-f739e425860a.json http://localhost:8080/fhir/
    curl -X POST -H "Content-Type: application/json" -d @./Aaron697_Stiedemann542_41166989-975d-4d17-b9de-17f94cb3eec1.json http://localhost:8080/fhir/
    curl -X POST -H "Content-Type: application/json" -d @./Abby752_Kuvalis369_2b083021-e93f-4991-bf49-fd4f20060ef8.json http://localhost:8080/fhir/
    
  3. Tüm hastaların test verilerini sunucuya yüklemek için aşağıdaki komutu çalıştırın:
    for f in *.json; do curl -X POST -H "Content-Type: application/json" -d @$f http://localhost:8080/fhir/ ; done
    
    Ancak bu işlemin tamamlanması uzun sürebilir ve codelab için gerekli değildir.
  4. http://localhost:8080/fhir/Patient/ URL'sini bir tarayıcıda açarak test verilerinin sunucuda mevcut olduğunu doğrulayın. HTTP 200 OK metnini ve FHIR paketinde hasta verilerini içeren sayfanın Response Body bölümünü, total sayısı içeren arama sonucu olarak görürsünüz.Sunucudaki verileri test etme

3. Android uygulamasını ayarlama

Kodu indirme

Bu codelab'in kodunu indirmek için Android FHIR SDK deposunu klonlayın: git clone https://github.com/google/android-fhir.git

Bu codelab'in başlangıç projesi codelabs/engine konumunda bulunur.

Uygulamayı Android Studio'ya aktarma

Başlangıç uygulamasını Android Studio'ya aktararak işe başlıyoruz.

Android Studio'yu açın, Import Project (Gradle, Eclipse ADT, etc.)'yi (Projeyi İçe Aktar (Gradle, Eclipse ADT vb.)) seçin ve daha önce indirdiğiniz kaynak kodundan codelabs/engine/ klasörünü belirleyin.

Android Studio başlangıç ekranı

Projenizi Gradle dosyalarıyla senkronize etme

Kolaylık sağlamak amacıyla FHIR Engine Library bağımlılıkları projeye önceden eklenmiştir. Bu sayede FHIR Engine Library'yi uygulamanıza entegre edebilirsiniz. Projenizin app/build.gradle.kts dosyasının sonuna aşağıdaki satırları ekleyin:

dependencies {
    // ...

    implementation("com.google.android.fhir:engine:1.1.0")
}

Tüm bağımlılıkların uygulamanızda kullanılabilir olduğundan emin olmak için bu noktada projenizi Gradle dosyalarıyla senkronize etmeniz gerekir.

Android Studio araç çubuğundan Projeyi Gradle Dosyalarıyla Senkronize Et'i (Gradle senkronizasyon düğmesi) seçin. Bağımlılıkların doğru şekilde çalıştığını kontrol etmek için uygulamayı tekrar çalıştırabilirsiniz.

Başlangıç uygulamasını çalıştırma

Projeyi Android Studio'ya aktardığınıza göre artık uygulamayı ilk kez çalıştırmaya hazırsınız.

Android Studio emülatörünü başlatın ve Android Studio araç çubuğunda Çalıştır'ı (Çalıştır düğmesi) tıklayın.

Hello World uygulaması

4. FHIR Engine örneği oluşturma

FHIR Engine'i Android uygulamanıza dahil etmek için FHIR Engine Kitaplığı'nı kullanmanız ve FHIR Engine'in bir örneğini başlatmanız gerekir. Aşağıda açıklanan adımlar, süreç boyunca size yol gösterecektir.

  1. Bu örnekte app/src/main/java/com/google/android/fhir/codelabs/engine içinde bulunan FhirApplication.kt olan uygulama sınıfınıza gidin.
  2. onCreate() yönteminin içine FHIR Engine'i ilk kullanıma hazırlamak için aşağıdaki kodu ekleyin:
      FhirEngineProvider.init(
          FhirEngineConfiguration(
            enableEncryptionIfSupported = true,
            RECREATE_AT_OPEN,
            ServerConfiguration(
              baseUrl = "http://10.0.2.2:8080/fhir/",
              httpLogger =
                HttpLogger(
                  HttpLogger.Configuration(
                    if (BuildConfig.DEBUG) HttpLogger.Level.BODY else HttpLogger.Level.BASIC,
                  ),
                ) {
                  Log.d("App-HttpLog", it)
                },
            ),
          ),
      )
    
    Notlar:
    • enableEncryptionIfSupported: Cihaz destekliyorsa veri şifrelemeyi etkinleştirir.
    • RECREATE_AT_OPEN: Veritabanı hata stratejisini belirler. Bu durumda, açılırken bir hata oluşursa veritabanı yeniden oluşturulur.
    • baseUrl in ServerConfiguration: Bu, FHIR sunucusunun temel URL'sidir. Sağlanan IP adresi 10.0.2.2, Android emülatöründen erişilebilen localhost için özel olarak ayrılmıştır. Daha fazla bilgi edinin.
  3. FhirApplication sınıfında, FHIR Engine'i geç başlatmak için aşağıdaki satırı ekleyin:
      private val fhirEngine: FhirEngine by
          lazy { FhirEngineProvider.getInstance(this) }
    
    Bu, FhirEngine örneğinin yalnızca ilk kez erişildiğinde oluşturulmasını sağlar. Uygulama başladığında hemen oluşturulmaz.
  4. Uygulamanızda daha kolay erişim için FhirApplication sınıfına aşağıdaki kolaylık yöntemini ekleyin:
    companion object {
        fun fhirEngine(context: Context) =
            (context.applicationContext as FhirApplication).fhirEngine
    }
    
    Bu statik yöntem, bağlamı kullanarak FHIR Engine örneğini uygulamanın herhangi bir yerinden almanıza olanak tanır.

5. Verileri FHIR sunucusuyla senkronize etme

  1. Yeni bir sınıf oluşturun DownloadWorkManagerImpl.kt. Bu derste, uygulamanın listeden bir sonraki kaynağı nasıl getireceğini ve indireceğini tanımlayacaksınız:
      class DownloadWorkManagerImpl : DownloadWorkManager {
        private val urls = LinkedList(listOf("Patient"))
    
        override suspend fun getNextRequest(): DownloadRequest? {
          val url = urls.poll() ?: return null
          return DownloadRequest.of(url)
        }
    
        override suspend fun getSummaryRequestUrls() = mapOf<ResourceType, String>()
    
        override suspend fun processResponse(response: Resource): Collection<Resource> {
          var bundleCollection: Collection<Resource> = mutableListOf()
          if (response is Bundle && response.type == Bundle.BundleType.SEARCHSET) {
            bundleCollection = response.entry.map { it.resource }
          }
          return bundleCollection
        }
      }
    
    Bu sınıfta, indirilmek istenen kaynak türlerinin bir sırası var. Yanıtları işler ve döndürülen paketten kaynakları çıkarır. Bu kaynaklar yerel veritabanına kaydedilir.
  2. Yeni bir sınıf oluşturun AppFhirSyncWorker.kt Bu sınıf, uygulamanın arka plan çalışanı kullanarak uzak FHIR sunucusuyla nasıl senkronize olacağını tanımlar.
    class AppFhirSyncWorker(appContext: Context, workerParams: WorkerParameters) :
      FhirSyncWorker(appContext, workerParams) {
    
      override fun getDownloadWorkManager() = DownloadWorkManagerImpl()
    
      override fun getConflictResolver() = AcceptLocalConflictResolver
    
      override fun getFhirEngine() = FhirApplication.fhirEngine(applicationContext)
    
      override fun getUploadStrategy() =
        UploadStrategy.forBundleRequest(
          methodForCreate = HttpCreateMethod.PUT,
          methodForUpdate = HttpUpdateMethod.PATCH,
          squash = true,
          bundleSize = 500,
        )
    }
    
    Burada, senkronizasyon için hangi indirme yöneticisinin, çakışma çözümleyicisinin ve FHIR motoru örneğinin kullanılacağını tanımladık.
  3. ViewModel'inizde (PatientListViewModel.kt) tek seferlik bir senkronizasyon mekanizması ayarlayacaksınız. Aşağıdaki kodu bulup triggerOneTimeSync() işlevine ekleyin:
    viewModelScope.launch {
          Sync.oneTimeSync<AppFhirSyncWorker>(getApplication())
            .shareIn(this, SharingStarted.Eagerly, 10)
            .collect { _pollState.emit(it) }
        }
    
    Bu eş yordam, daha önce tanımladığımız AppFhirSyncWorker'ı kullanarak FHIR sunucusuyla tek seferlik bir senkronizasyon başlatır. Ardından, senkronizasyon işleminin durumuna göre kullanıcı arayüzünü günceller.
  4. PatientListFragment.kt dosyasında handleSyncJobStatus işlevinin gövdesini güncelleyin:
    when (syncJobStatus) {
        is SyncJobStatus.Finished -> {
            Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show()
            viewModel.searchPatientsByName("")
        }
        else -> {}
    }
    
    Burada, senkronizasyon işlemi tamamlandığında kullanıcıyı bilgilendiren bir kısa mesaj gösterilir ve ardından uygulama, boş bir adla arama yaparak tüm hastaları gösterir.

Her şey ayarlandığına göre uygulamanızı çalıştırın. Menüdeki Sync düğmesini tıklayın. Her şey doğru şekilde çalışıyorsa yerel FHIR sunucunuzdaki hastaların indirilip uygulamada gösterildiğini görmeniz gerekir.

Hasta listesi

6. Hasta verilerini değiştirme ve yükleme

Bu bölümde, hasta verilerini belirli ölçütlere göre değiştirme ve güncellenen verileri FHIR sunucunuza yükleme sürecinde size yol göstereceğiz. Özellikle, Wakefield ve Taunton'de ikamet eden hastaların adres şehirlerini değiştireceğiz.

1. adım: PatientListViewModel'da değişiklik mantığını ayarlayın

Bu bölümdeki kod, PatientListViewModel içindeki triggerUpdate işlevine eklenir.

  1. FHIR Engine'e erişme:PatientListViewModel.kt içinde FHIR Engine'e referans alarak başlayın.
    viewModelScope.launch {
       val fhirEngine = FhirApplication.fhirEngine(getApplication())
    
    Bu kod, ViewModel'in kapsamı içinde bir eş yordam başlatır ve FHIR motorunu başlatır.
  2. Wakefield'daki hastaları arama:Adres şehri Wakefield olan hastaları aramak için FHIR motorunu kullanın.
    val patientsFromWakefield =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Wakefield"
             }
           )
         }
    
    Burada, hastaları adreslerine göre filtrelemek için FHIR motorunun search yöntemini kullanıyoruz. Sonuç, Wakefield'daki hastaların listesi olur.
  3. Taunton'daki hastaları arama:Benzer şekilde, Taunton şehir adresine sahip hastaları arayın.
    val patientsFromTaunton =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Taunton"
             }
           )
         }
    
    Artık iki hasta listemiz var: biri Wakefield'dan, diğeri ise Taunton'dan.
  4. Hasta Adreslerini Değiştirme:patientsFromWakefield listesindeki her hastayı inceleyin, şehirlerini Taunton olarak değiştirin ve FHIR motorunda güncelleyin.
    patientsFromWakefield.forEach {
         it.resource.address.first().city = "Taunton"
         fhirEngine.update(it.resource)
    }
    
    Aynı şekilde, patientsFromTaunton listesindeki her hastanın şehrini Wakefield olarak değiştirmek için güncelleyin.
    patientsFromTaunton.forEach {
         it.resource.address.first().city = "Wakefield"
         fhirEngine.update(it.resource)
    }
    
  5. Senkronizasyonu Başlatma:Verileri yerel olarak değiştirdikten sonra, verilerin FHIR sunucusunda güncellenmesini sağlamak için tek seferlik bir senkronizasyon başlatın.
    triggerOneTimeSync()
    }
    
    Kapatma kümesi }, başlangıçta başlatılan eş yordamın sonunu belirtir.

2. adım: İşlevselliği test edin

  1. Kullanıcı arayüzü testi:Uygulamanızı çalıştırın. Menüdeki Update düğmesini tıklayın. Aaron697 ve Abby752 adlı hastaların adres şehirlerinin değiştirildiğini görürsünüz.
  2. Sunucu Doğrulaması:Bir tarayıcı açıp http://localhost:8080/fhir/Patient/ adresine gidin. Aaron697 ve Abby752 hastalarının adres şehri bilgisinin yerel FHIR sunucusunda güncellendiğini doğrulayın.

Bu adımları uygulayarak hasta verilerini değiştirmek ve değişiklikleri FHIR sunucunuzla senkronize etmek için bir mekanizmayı başarıyla uyguladınız.

7. Hastaları ada göre arama

Hastaları adlarına göre aramak, bilgileri kullanıcı dostu bir şekilde almanın bir yolu olabilir. Bu bölümde, bu özelliği uygulamanıza ekleme sürecinde size yol göstereceğiz.

1. adım: İşlev imzasını güncelleyin

PatientListViewModel.kt dosyanıza gidin ve searchPatientsByName adlı işlevi bulun. Bu işleve kod ekleyeceğiz.

Sonuçları sağlanan ad sorgusuna göre filtrelemek ve kullanıcı arayüzünün güncellenmesi için sonuçları yayınlamak üzere aşağıdaki koşullu kod bloğunu ekleyin:

    viewModelScope.launch {
      val fhirEngine = FhirApplication.fhirEngine(getApplication())
      if (nameQuery.isNotEmpty()) {
        val searchResult = fhirEngine.search<Patient> {
          filter(
            Patient.NAME,
            {
              modifier = StringFilterModifier.CONTAINS
              value = nameQuery
            },
          )
        }
        liveSearchedPatients.value  =  searchResult.map { it.resource }
      }
    }

Burada, nameQuery boş değilse arama işlevi, sonuçları yalnızca adlarında belirtilen sorguyu içeren hastaları içerecek şekilde filtreler.

2. adım: Yeni arama işlevini test edin

  1. Uygulamayı yeniden başlatın:Bu değişiklikleri yaptıktan sonra uygulamanızı yeniden oluşturup çalıştırın.
  2. Hasta Arama: Hasta listesi ekranında arama işlevini kullanın. Artık hasta listesini buna göre filtrelemek için bir ad (veya adın bir bölümü) girebilirsiniz.

Bu adımları tamamladığınızda, kullanıcıların hastaları adlarına göre verimli bir şekilde arama olanağı sunarak uygulamanızı geliştirmiş olursunuz. Bu sayede kullanıcı deneyimi ve veri alma verimliliği önemli ölçüde artırılabilir.

8. Tebrikler!

Uygulamanızdaki FHIR kaynaklarını yönetmek için FHIR Engine Kitaplığı'nı kullanmış olmanız gerekir:

  • FHIR kaynaklarını bir FHIR sunucusuyla senkronize etmek için Sync API'yi kullanma
  • Yerel FHIR kaynaklarını oluşturmak, okumak, güncellemek ve silmek için Data Access API'yi kullanma
  • Yerel FHIR kaynaklarını aramak için Search API'yi kullanma

İşlediğimiz konular

  • Yerel bir HAPI FHIR sunucusu oluşturma
  • Yerel HAPI FHIR sunucusuna test verileri yükleme
  • FHIR Engine kitaplığını kullanarak Android uygulaması oluşturma
  • FHIR Engine Kitaplığı'nda Sync API, Data Access API ve Search API'yi kullanma

Sonraki Adımlar

  • FHIR Engine Kitaplığı'nın belgelerini inceleyin.
  • Search API'nin ileri seviye özelliklerini keşfedin
  • FHIR Engine Kitaplığı'nı kendi Android uygulamanızda uygulama

Daha Fazla Bilgi