FHIR Engine लाइब्रेरी का इस्तेमाल करके, FHIR के संसाधन मैनेज करें

1. शुरू करने से पहले

आपको क्या बनाना है

इस कोडलैब में, FHIR Engine Library का इस्तेमाल करके एक Android ऐप्लिकेशन बनाया जाएगा. आपका ऐप्लिकेशन, FHIR सर्वर से FHIR संसाधनों को डाउनलोड करने के लिए FHIR Engine Library का इस्तेमाल करेगा. साथ ही, सर्वर पर स्थानीय बदलावों को अपलोड करेगा.

आपको क्या सीखने को मिलेगा

  • Docker का इस्तेमाल करके, लोकल HAPI FHIR सर्वर बनाने का तरीका
  • FHIR Engine Library को अपने Android ऐप्लिकेशन में इंटिग्रेट करने का तरीका
  • FHIR संसाधनों को डाउनलोड और अपलोड करने के लिए, एक बार या समय-समय पर होने वाले काम को सेट अप करने के लिए, Sync API का इस्तेमाल कैसे करें
  • Search API का इस्तेमाल कैसे करें
  • स्थानीय तौर पर FHIR संसाधन बनाने, पढ़ने, अपडेट करने, और मिटाने के लिए, डेटा ऐक्सेस करने वाले एपीआई का इस्तेमाल कैसे करें

आपको किन चीज़ों की ज़रूरत होगी

  • Docker (Docker पाएं)
  • Android Studio (v4.1.2+) का नया वर्शन
  • Android 7.0 Nougat या इसके बाद के वर्शन पर चलने वाला Android Emulator या कोई Android डिवाइस
  • सैंपल कोड
  • Kotlin में Android डेवलपमेंट की बुनियादी जानकारी

अगर आपने पहले कभी Android ऐप्लिकेशन नहीं बनाए हैं, तो अपना पहला ऐप्लिकेशन बनाकर शुरुआत करें.

2. टेस्ट डेटा के साथ लोकल HAPI FHIR सर्वर सेट अप करना

HAPI FHIR, एक लोकप्रिय ओपन सोर्स FHIR सर्वर है. हम अपने कोडलैब में, Android ऐप्लिकेशन के लिए लोकल HAPI FHIR सर्वर का इस्तेमाल करते हैं, ताकि ऐप्लिकेशन उससे कनेक्ट हो सके.

लोकल HAPI FHIR सर्वर सेट अप करना

  1. HAPI FHIR की नई इमेज पाने के लिए, टर्मिनल में यह कमांड चलाएं
    docker pull hapiproject/hapi:latest
    
  2. HAPI FHIR कंटेनर बनाएं. इसके लिए, पहले से डाउनलोड की गई इमेज hapiproject/hapi को चलाने के लिए Docker Desktop का इस्तेमाल करें या यहां दिया गया निर्देश चलाएं
    docker run -p 8080:8080 hapiproject/hapi:latest
    
    ज़्यादा जानें.
  3. ब्राउज़र में यूआरएल http://localhost:8080/ खोलकर, सर्वर की जांच करें. आपको HAPI FHIR का वेब इंटरफ़ेस दिखेगा.HAPI FHIR का वेब इंटरफ़ेस

टेस्ट डेटा के साथ लोकल HAPI FHIR सर्वर को पॉप्युलेट करना

हमारे ऐप्लिकेशन की जांच करने के लिए, हमें सर्वर पर कुछ टेस्ट डेटा की ज़रूरत होगी. हम Synthea से जनरेट किए गए सिंथेटिक डेटा का इस्तेमाल करेंगे.

  1. सबसे पहले, हमें synthea-samples से सैंपल डेटा डाउनलोड करना होगा. synthea_sample_data_fhir_r4_sep2019.zip को डाउनलोड और एक्सट्रैक्ट करें. अनज़िप किए गए सैंपल डेटा में कई .json फ़ाइलें होती हैं. इनमें से हर फ़ाइल, किसी एक मरीज़ के लेन-देन का बंडल होती है.
  2. हम तीन मरीज़ों के लिए टेस्ट डेटा को स्थानीय HAPI FHIR सर्वर पर अपलोड करेंगे. JSON फ़ाइलों वाली डायरेक्ट्री में यह कमांड चलाएं
    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. सभी मरीज़ों के टेस्ट का डेटा सर्वर पर अपलोड करने के लिए, यह कमांड चलाएं
    for f in *.json; do curl -X POST -H "Content-Type: application/json" -d @$f http://localhost:8080/fhir/ ; done
    
    हालांकि, इसमें लंबा समय लग सकता है और कोडलैब के लिए यह ज़रूरी नहीं है.
  4. पुष्टि करें कि सर्वर पर टेस्ट डेटा उपलब्ध है. इसके लिए, ब्राउज़र में यूआरएल http://localhost:8080/fhir/Patient/ खोलें. आपको खोज के नतीजे के तौर पर, HTTP 200 OK टेक्स्ट और Response Body सेक्शन दिखना चाहिए. इसमें, मरीज़ का डेटा शामिल होता है. यह डेटा, FHIR बंडल में होता है. साथ ही, इसमें total की संख्या भी दिखती है.सर्वर पर डेटा की जांच करना

3. Android ऐप्लिकेशन सेट अप करना

कोड डाउनलोड करना

इस कोडलैब के लिए कोड डाउनलोड करने के लिए, Android FHIR SDK रिपॉज़िटरी को क्लोन करें: git clone https://github.com/google/android-fhir.git

इस कोडलैब का स्टार्टर प्रोजेक्ट, codelabs/engine में मौजूद है.

ऐप्लिकेशन को Android Studio में इंपोर्ट करना

हम Android Studio में स्टार्टर ऐप्लिकेशन इंपोर्ट करके शुरू करते हैं.

Android Studio खोलें. इसके बाद, Import Project (Gradle, Eclipse ADT, etc.) को चुनें. अब सोर्स कोड से codelabs/engine/ फ़ोल्डर चुनें. यह वही सोर्स कोड होना चाहिए जिसे आपने पहले डाउनलोड किया था.

Android Studio की शुरुआती स्क्रीन

अपने प्रोजेक्ट को Gradle फ़ाइलों के साथ सिंक करना

आपकी सुविधा के लिए, FHIR Engine Library की डिपेंडेंसी को प्रोजेक्ट में पहले ही जोड़ दिया गया है. इससे आपको अपने ऐप्लिकेशन में FHIR Engine Library को इंटिग्रेट करने की अनुमति मिलती है. अपने प्रोजेक्ट की app/build.gradle.kts फ़ाइल के आखिर में मौजूद इन लाइनों को देखें:

dependencies {
    // ...

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

यह पक्का करने के लिए कि आपके ऐप्लिकेशन के लिए सभी डिपेंडेंसी उपलब्ध हैं, आपको इस समय अपने प्रोजेक्ट को ग्रेडल फ़ाइलों के साथ सिंक करना चाहिए.

Android Studio के टूलबार में जाकर, Gradle फ़ाइलों के साथ प्रोजेक्ट सिंक करें (Gradle सिंक करने का बटन) को चुनें. यह देखने के लिए कि डिपेंडेंसी सही तरीके से काम कर रही हैं या नहीं, ऐप्लिकेशन को फिर से चलाया जा सकता है.

स्टार्टर ऐप्लिकेशन चलाना

प्रोजेक्ट को Android Studio में इंपोर्ट करने के बाद, अब ऐप्लिकेशन को पहली बार चलाने के लिए तैयार हैं.

Android Studio Emulator शुरू करें. इसके बाद, Android Studio टूलबार में मौजूद 'चलाएं' ('चलाएं' बटन) पर क्लिक करें.

Hello World ऐप्लिकेशन

4. FHIR Engine इंस्टेंस बनाना

FHIR Engine को अपने Android ऐप्लिकेशन में शामिल करने के लिए, आपको FHIR Engine Library का इस्तेमाल करना होगा. साथ ही, FHIR Engine का इंस्टेंस शुरू करना होगा. यहां दिए गए तरीके से, आपको प्रोसेस पूरी करने में मदद मिलेगी.

  1. अपनी ऐप्लिकेशन क्लास पर जाएं. इस उदाहरण में, यह FhirApplication.kt है और app/src/main/java/com/google/android/fhir/codelabs/engine में मौजूद है.
  2. FHIR Engine को शुरू करने के लिए, onCreate() तरीके में यह कोड जोड़ें:
      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)
                },
            ),
          ),
      )
    
    ध्यान दें:
    • enableEncryptionIfSupported: अगर डिवाइस पर डेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा काम करती है, तो इसे चालू करता है.
    • RECREATE_AT_OPEN: इससे डेटाबेस से जुड़ी गड़बड़ी की रणनीति तय होती है. इस मामले में, डेटाबेस को फिर से बनाया जाता है. ऐसा तब होता है, जब डेटाबेस को खोलने पर कोई गड़बड़ी होती है.
    • baseUrl in ServerConfiguration: यह FHIR सर्वर का बेस यूआरएल है. दिया गया आईपी पता 10.0.2.2, खास तौर पर लोकल होस्ट के लिए रिज़र्व किया गया है. इसे Android एम्युलेटर से ऐक्सेस किया जा सकता है. ज़्यादा जानें.
  3. FhirApplication क्लास में, FHIR Engine को लेज़ी इंस्टैंशिएट करने के लिए, यह लाइन जोड़ें:
      private val fhirEngine: FhirEngine by
          lazy { FhirEngineProvider.getInstance(this) }
    
    इससे यह पक्का होता है कि FhirEngine इंस्टेंस सिर्फ़ तब बनाया जाता है, जब इसे पहली बार ऐक्सेस किया जाता है. ऐप्लिकेशन शुरू होने पर इसे तुरंत नहीं बनाया जाता.
  4. अपने पूरे ऐप्लिकेशन में आसानी से ऐक्सेस करने के लिए, FhirApplication क्लास में यहां दिया गया तरीका जोड़ें:
    companion object {
        fun fhirEngine(context: Context) =
            (context.applicationContext as FhirApplication).fhirEngine
    }
    
    इस स्टैटिक तरीके से, कॉन्टेक्स्ट का इस्तेमाल करके ऐप्लिकेशन में कहीं से भी FHIR Engine इंस्टेंस को वापस पाया जा सकता है.

5. FHIR सर्वर के साथ डेटा सिंक करना

  1. नई क्लास बनाएं DownloadWorkManagerImpl.kt. इस क्लास में, यह तय किया जाता है कि ऐप्लिकेशन, डाउनलोड करने के लिए सूची से अगली संसाधन फ़ाइल कैसे फ़ेच करेगा.:
      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
        }
      }
    
    इस क्लास में, डाउनलोड किए जाने वाले संसाधनों के टाइप की एक सूची है. यह जवाबों को प्रोसेस करता है और बंडल से संसाधनों को निकालता है. इसके बाद, इन्हें लोकल डेटाबेस में सेव कर दिया जाता है.
  2. नई क्लास बनाएं AppFhirSyncWorker.kt यह क्लास तय करती है कि बैकग्राउंड वर्कर का इस्तेमाल करके, ऐप्लिकेशन रिमोट FHIR सर्वर के साथ कैसे सिंक होगा.
    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,
        )
    }
    
    यहां हमने यह तय किया है कि सिंक करने के लिए, किस डाउनलोड मैनेजर, कॉन्फ़्लिक्ट रिज़ॉल्वर, और FHIR इंजन इंस्टेंस का इस्तेमाल किया जाएगा.
  3. अपने ViewModel, PatientListViewModel.kt में, आपको एक बार सिंक करने का तरीका सेट अप करना होगा. इस कोड को ढूंढें और triggerOneTimeSync() फ़ंक्शन में जोड़ें:
    viewModelScope.launch {
          Sync.oneTimeSync<AppFhirSyncWorker>(getApplication())
            .shareIn(this, SharingStarted.Eagerly, 10)
            .collect { _pollState.emit(it) }
        }
    
    यह कोरूटीन, AppFhirSyncWorker का इस्तेमाल करके FHIR सर्वर के साथ एक बार सिंक करने की प्रोसेस शुरू करता है. हमने AppFhirSyncWorker को पहले ही तय कर लिया था. इसके बाद, यह सिंक प्रोसेस की स्थिति के आधार पर यूज़र इंटरफ़ेस (यूआई) को अपडेट करेगा.
  4. PatientListFragment.kt फ़ाइल में, handleSyncJobStatus फ़ंक्शन के मुख्य हिस्से को अपडेट करें:
    when (syncJobStatus) {
        is SyncJobStatus.Finished -> {
            Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show()
            viewModel.searchPatientsByName("")
        }
        else -> {}
    }
    
    यहां सिंक प्रोसेस पूरी होने पर, उपयोगकर्ता को एक सूचना वाला मैसेज दिखेगा. इसके बाद, ऐप्लिकेशन में सभी मरीज़ों की जानकारी दिखेगी. इसके लिए, बिना नाम के खोज फ़ंक्शन का इस्तेमाल किया जाएगा.

अब जब सब कुछ सेट अप हो गया है, तो अपना ऐप्लिकेशन चलाएं. मेन्यू में मौजूद Sync बटन पर क्लिक करें. अगर सब कुछ ठीक से काम करता है, तो आपको अपने लोकल FHIR सर्वर से मरीज़ों की जानकारी डाउनलोड होती हुई दिखेगी. साथ ही, यह जानकारी ऐप्लिकेशन में दिखेगी.

मरीज़ों की सूची

6. मरीज़ के डेटा में बदलाव करना और उसे अपलोड करना

इस सेक्शन में, हम आपको कुछ शर्तों के आधार पर मरीज़ के डेटा में बदलाव करने और अपडेट किए गए डेटा को अपने FHIR सर्वर पर अपलोड करने की प्रोसेस के बारे में बताएंगे. खास तौर पर, हम Wakefield और Taunton में रहने वाले मरीज़ों के पते वाले शहरों की जानकारी बदल देंगे.

पहला चरण: PatientListViewModel में बदलाव करने की सुविधा सेट अप करना

इस सेक्शन में मौजूद कोड को PatientListViewModel में triggerUpdate फ़ंक्शन में जोड़ा जाता है

  1. FHIR Engine को ऐक्सेस करना:PatientListViewModel.kt में FHIR Engine का रेफ़रंस पाकर शुरू करें.
    viewModelScope.launch {
       val fhirEngine = FhirApplication.fhirEngine(getApplication())
    
    यह कोड, ViewModel के स्कोप में एक कोरूटीन लॉन्च करता है और FHIR इंजन को शुरू करता है.
  2. वेकफ़ील्ड के मरीज़ों को खोजें:FHIR इंजन का इस्तेमाल करके, उन मरीज़ों को खोजें जिनके पते में शहर का नाम Wakefield है.
    val patientsFromWakefield =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Wakefield"
             }
           )
         }
    
    यहां, हम FHIR इंजन के search तरीके का इस्तेमाल करके, मरीज़ों को उनके पते के शहर के हिसाब से फ़िल्टर कर रहे हैं. इसके नतीजे में, वेकफ़ील्ड के मरीज़ों की सूची दिखेगी.
  3. टॉन्टन के मरीज़ों को खोजें:इसी तरह, Taunton शहर के पते वाले मरीज़ों को खोजें.
    val patientsFromTaunton =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Taunton"
             }
           )
         }
    
    अब हमारे पास मरीज़ों की दो सूचियां हैं - एक वेकफ़ील्ड से और दूसरी टॉनटन से.
  4. मरीज़ के पते में बदलाव करना:patientsFromWakefield सूची में मौजूद हर मरीज़ की जानकारी देखें. उनके शहर का नाम बदलकर Taunton करें. इसके बाद, FHIR इंजन में उनकी जानकारी अपडेट करें.
    patientsFromWakefield.forEach {
         it.resource.address.first().city = "Taunton"
         fhirEngine.update(it.resource)
    }
    
    इसी तरह, patientsFromTaunton सूची में मौजूद हर मरीज़ की जानकारी अपडेट करें, ताकि उनके शहर का नाम बदलकर Wakefield हो जाए.
    patientsFromTaunton.forEach {
         it.resource.address.first().city = "Wakefield"
         fhirEngine.update(it.resource)
    }
    
  5. सिंक शुरू करें:डेटा में स्थानीय तौर पर बदलाव करने के बाद, एक बार सिंक करने की सुविधा चालू करें. इससे यह पक्का किया जा सकेगा कि FHIR सर्वर पर डेटा अपडेट हो गया है.
    triggerOneTimeSync()
    }
    
    क्लोज़िंग ब्रेस } से पता चलता है कि शुरुआत में लॉन्च किया गया कोरूटीन खत्म हो गया है.

दूसरा चरण: सुविधा की जांच करना

  1. यूज़र इंटरफ़ेस (यूआई) की टेस्टिंग:अपना ऐप्लिकेशन चलाएं. मेन्यू में मौजूद Update बटन पर क्लिक करें. आपको मरीज़ Aaron697 और Abby752 के पते के शहर की जानकारी बदली हुई दिखेगी.
  2. सर्वर से पुष्टि करना:कोई ब्राउज़र खोलें और http://localhost:8080/fhir/Patient/ पर जाएं. पुष्टि करें कि मरीज़ों Aaron697 और Abby752 के पते में शहर का नाम, स्थानीय FHIR सर्वर पर अपडेट हो गया हो.

इन चरणों को पूरा करने के बाद, आपने मरीज़ के डेटा में बदलाव करने और उन बदलावों को अपने FHIR सर्वर के साथ सिंक करने का तरीका लागू कर लिया है.

7. नाम के हिसाब से मरीज़ों को खोजना

मरीज़ों को उनके नाम से खोजने पर, जानकारी आसानी से मिल सकती है. यहां हम आपको अपने ऐप्लिकेशन में इस सुविधा को लागू करने की प्रोसेस के बारे में बताएंगे.

पहला चरण: फ़ंक्शन सिग्नेचर अपडेट करना

अपनी PatientListViewModel.kt फ़ाइल पर जाएं और searchPatientsByName नाम का फ़ंक्शन ढूंढें. हम इस फ़ंक्शन में कोड जोड़ेंगे.

नाम से जुड़ी क्वेरी के आधार पर नतीजों को फ़िल्टर करने और यूज़र इंटरफ़ेस (यूआई) को अपडेट करने के लिए, यहां दिए गए कोड ब्लॉक को शामिल करें:

    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 }
      }
    }

यहां, अगर nameQuery खाली नहीं है, तो SEARCH फ़ंक्शन, नतीजों को फ़िल्टर करेगा. इसमें सिर्फ़ उन मरीज़ों के नाम शामिल होंगे जिनमें दी गई क्वेरी शामिल है.

दूसरा चरण: नई खोज की सुविधा को आज़माना

  1. ऐप्लिकेशन को फिर से लॉन्च करें:इन बदलावों को करने के बाद, अपने ऐप्लिकेशन को फिर से बनाएं और चलाएं.
  2. मरीज़ों को खोजें: मरीज़ों की सूची वाली स्क्रीन पर, खोजने की सुविधा का इस्तेमाल करें. अब आपके पास, मरीज़ों की सूची को फ़िल्टर करने के लिए, नाम (या नाम का कुछ हिस्सा) डालने का विकल्प होगा.

इन चरणों को पूरा करने के बाद, आपने अपने ऐप्लिकेशन को बेहतर बना लिया है. अब उपयोगकर्ता, मरीजों को उनके नाम से आसानी से खोज सकते हैं. इससे उपयोगकर्ता अनुभव को बेहतर बनाने और डेटा को तेज़ी से ऐक्सेस करने में मदद मिलती है.

8. बधाई हो!

आपने अपने ऐप्लिकेशन में FHIR संसाधनों को मैनेज करने के लिए, FHIR Engine Library का इस्तेमाल किया है:

  • FHIR संसाधनों को FHIR सर्वर के साथ सिंक करने के लिए, Sync API का इस्तेमाल करना
  • Data Access API का इस्तेमाल करके, स्थानीय FHIR संसाधन बनाना, पढ़ना, अपडेट करना, और मिटाना
  • स्थानीय FHIR संसाधनों को खोजने के लिए, Search API का इस्तेमाल करना

हमने क्या-क्या कवर किया है

  • स्थानीय HAPI FHIR सर्वर सेट अप करने का तरीका
  • स्थानीय HAPI FHIR सर्वर पर टेस्ट डेटा अपलोड करने का तरीका
  • FHIR Engine Library का इस्तेमाल करके, Android ऐप्लिकेशन बनाने का तरीका
  • FHIR Engine Library में Sync API, Data Access API, और Search API का इस्तेमाल कैसे करें

अगले चरण

  • FHIR Engine Library से जुड़ा दस्तावेज़ देखें
  • Search API की ऐडवांस सुविधाओं के बारे में जानें
  • अपने Android ऐप्लिकेशन में FHIR Engine Library लागू करना

ज़्यादा जानें