مدیریت منابع FHIR با استفاده از کتابخانه موتور FHIR

1. قبل از شروع

چیزی که خواهی ساخت

در این کد لبه، شما با استفاده از FHIR Engine Library، یک برنامه اندرویدی خواهید ساخت. برنامه شما از کتابخانه موتور FHIR برای دانلود منابع FHIR از سرور FHIR و آپلود هرگونه تغییر محلی در سرور استفاده می کند.

چیزی که یاد خواهید گرفت

  • نحوه ایجاد یک سرور محلی HAPI FHIR با استفاده از Docker
  • چگونه کتابخانه موتور FHIR را در برنامه اندروید خود ادغام کنید
  • نحوه استفاده از Sync API برای تنظیم یک کار یک بار یا دوره ای برای دانلود و آپلود منابع FHIR
  • نحوه استفاده از Search API
  • نحوه استفاده از API های دسترسی به داده برای ایجاد، خواندن، به روز رسانی و حذف منابع FHIR به صورت محلی

آنچه شما نیاز دارید

اگر قبلاً برنامه‌های Android ساخته نشده‌اید، می‌توانید با ساخت اولین برنامه خود شروع کنید.

2. یک سرور محلی HAPI FHIR با داده های آزمایشی راه اندازی کنید

HAPI FHIR یک سرور منبع باز محبوب FHIR است. ما از یک سرور محلی HAPI FHIR در لبه کد خود برای اتصال برنامه Android استفاده می کنیم.

سرور محلی HAPI FHIR را راه اندازی کنید

  1. دستور زیر را در ترمینال اجرا کنید تا آخرین تصویر HAPI FHIR را دریافت کنید
    docker pull hapiproject/hapi:latest
    
  2. با استفاده از Docker Desktop برای اجرای تصویر دانلود شده hapiproject/hapi یا اجرای دستور زیر، یک کانتینر HAPI FHIR ایجاد کنید.
    docker run -p 8080:8080 hapiproject/hapi:latest
    
    بیشتر بدانید.
  3. سرور را با باز کردن URL http://localhost:8080/ در مرورگر بررسی کنید. شما باید رابط وب HAPI FHIR را ببینید. HAPI FHIR web interface

سرور محلی 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
    
    با این حال، تکمیل این کار می‌تواند زمان زیادی طول بکشد و برای Codelab ضروری نیست.
  4. با باز کردن URL http://localhost:8080/fhir/Patient/ در یک مرورگر، بررسی کنید که داده‌های آزمایش در سرور در دسترس هستند. باید متن HTTP 200 OK و بخش Response Body صفحه حاوی داده‌های بیمار را در یک بسته FHIR به عنوان نتیجه جستجو با تعداد total مشاهده کنید. Test data on server

3. برنامه اندروید را راه اندازی کنید

کد را دانلود کنید

برای دانلود کد این نرم افزار کد، مخزن Android FHIR SDK را کلون کنید: git clone https://github.com/google/android-fhir.git

پروژه شروع برای این کد لبه در codelabs/engine قرار دارد.

برنامه را به اندروید استودیو وارد کنید

ما با وارد کردن برنامه شروع به Android Studio شروع می کنیم.

Android Studio را باز کنید، Import Project (Gradle، Eclipse ADT، و غیره) را انتخاب کنید و پوشه codelabs/engine/ از کد منبعی که قبلا دانلود کرده اید انتخاب کنید.

Android Studio start screen

پروژه خود را با فایل های Gradle همگام سازی کنید

برای راحتی شما، وابستگی های کتابخانه موتور FHIR قبلاً به پروژه اضافه شده است. این به شما امکان می دهد کتابخانه موتور FHIR را در برنامه خود ادغام کنید. خطوط زیر را تا انتهای فایل app/build.gradle.kts پروژه خود رعایت کنید:

dependencies {
    // ...

    implementation("com.google.android.fhir:engine:0.1.0-beta05")
}

برای اطمینان از اینکه همه وابستگی ها برای برنامه شما در دسترس هستند، باید پروژه خود را با فایل های gradle در این مرحله همگام کنید.

انتخاب پروژه همگام سازی با فایل های Gradle ( Gradle sync button )از نوار ابزار Android Studio. همچنین می‌توانید برنامه را دوباره اجرا کنید تا بررسی کنید وابستگی‌ها درست کار می‌کنند.

برنامه استارتر را اجرا کنید

اکنون که پروژه را به اندروید استودیو وارد کرده اید، برای اولین بار آماده اجرای برنامه هستید.

شبیه ساز Android Studio را راه اندازی کنید و روی Run کلیک کنید ( Run button ) در نوار ابزار Android Studio.

اپلیکیشن Hello World

4. نمونه FHIR Engine را ایجاد کنید

برای ادغام FHIR Engine در برنامه Android خود، باید از FHIR Engine Library استفاده کنید و نمونه ای از FHIR Engine را راه اندازی کنید. مراحل ذکر شده در زیر شما را از طریق این فرآیند راهنمایی می کند.

  1. به کلاس Application خود بروید، که در این مثال FhirApplication.kt است، که در app/src/main/java/com/google/android/fhir/codelabs/engine قرار دارد.
  2. در متد onCreate() کد زیر را برای مقداردهی اولیه FHIR Engine اضافه کنید:
      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 در ServerConfiguration : این نشانی اینترنتی اصلی سرور FHIR است. آدرس IP ارائه شده 10.0.2.2 به طور ویژه برای میزبان محلی رزرو شده است که از شبیه ساز اندروید قابل دسترسی است. بیشتر بدانید.
  3. در کلاس FhirApplication ، خط زیر را اضافه کنید تا به صورت تنبلی موتور FHIR را نمونه سازی کنید:
      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)
    }
    
    در اینجا، ما تعریف کرده‌ایم که از کدام دانلود منیجر، حل‌کننده تضاد، و نمونه موتور FHIR برای همگام‌سازی استفاده کنیم.
  3. در ViewModel خود، PatientListViewModel.kt ، یک مکانیسم همگام‌سازی یک‌باره راه‌اندازی می‌کنید. این کد را به تابع triggerOneTimeSync() بیابید و اضافه کنید:
    viewModelScope.launch {
          Sync.oneTimeSync<AppFhirSyncWorker>(getApplication())
            .shareIn(this, SharingStarted.Eagerly, 10)
            .collect { _pollState.emit(it) }
        }
    
    این برنامه با استفاده از AppFhirSyncWorker که قبلاً تعریف کردیم، یک همگام سازی یکباره با سرور FHIR را آغاز می کند. سپس UI را بر اساس وضعیت فرآیند همگام سازی به روز می کند.
  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 تعویض خواهیم کرد.

مرحله 1 : منطق اصلاح را در PatientListViewModel تنظیم کنید

کد این بخش به تابع triggerUpdate در PatientListViewModel اضافه می شود

  1. به موتور FHIR دسترسی پیدا کنید : با مراجعه به موتور FHIR در PatientListViewModel.kt شروع کنید.
    viewModelScope.launch {
       val fhirEngine = FhirApplication.fhirEngine(getApplication())
    
    این کد یک coroutine را در محدوده ViewModel راه اندازی می کند و موتور FHIR را مقداردهی اولیه می کند.
  2. جستجوی بیماران از Wakefield : از موتور FHIR برای جستجوی بیماران با آدرس شهر Wakefield استفاده کنید.
    val patientsFromWakefield =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Wakefield"
             }
           )
         }
    
    در اینجا، ما از روش search موتور FHIR برای فیلتر کردن بیماران بر اساس شهر آدرس آنها استفاده می کنیم. نتیجه لیستی از بیماران از Wakefield خواهد بود.
  3. جستجوی بیماران از Taunton : به طور مشابه، بیماران را با آدرس شهر Taunton جستجو کنید.
    val patientsFromTaunton =
         fhirEngine.search<Patient> {
           filter(
             Patient.ADDRESS_CITY,
             {
               modifier =  StringFilterModifier.MATCHES_EXACTLY
               value = "Taunton"
             }
           )
         }
    
    ما اکنون دو لیست از بیماران داریم - یکی از Wakefield و دیگری از 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()
    }
    
    پرانتز بسته شدن } نشان دهنده پایان کاری است که در ابتدا راه اندازی شده است.

مرحله 2 : عملکرد را آزمایش کنید

  1. تست رابط کاربری : برنامه خود را اجرا کنید. روی دکمه Update در منو کلیک کنید. شما باید آدرس شهرهای بیمار Aaron697 و Abby752 را ببینید.
  2. تأیید سرور : یک مرورگر را باز کنید و به http://localhost:8080/fhir/Patient/ بروید. بررسی کنید که آدرس شهر بیماران Aaron697 و Abby752 در سرور محلی FHIR به روز شده باشد.

با دنبال کردن این مراحل، مکانیزمی را برای تغییر داده های بیمار و همگام سازی تغییرات با سرور FHIR خود با موفقیت پیاده سازی کرده اید.

7. جستجوی بیماران بر اساس نام

جستجوی بیماران با نام آنها می تواند یک روش کاربرپسند برای بازیابی اطلاعات ارائه دهد. در اینجا، شما را از طریق فرآیند پیاده سازی این ویژگی در برنامه خود راهنمایی می کنیم.

مرحله 1 : امضای تابع را به روز کنید

به فایل 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 خالی نباشد، تابع جستجو نتایج را به گونه‌ای فیلتر می‌کند که فقط شامل بیمارانی می‌شود که نام آنها شامل پرس و جوی مشخص شده است.

مرحله 2 : عملکرد جستجوی جدید را آزمایش کنید

  1. برنامه را مجدداً راه اندازی کنید : پس از انجام این تغییرات، برنامه خود را دوباره بسازید و اجرا کنید.
  2. جستجوی بیماران : در صفحه فهرست بیماران، از قابلیت جستجو استفاده کنید. اکنون باید بتوانید نام (یا بخشی از نام) را وارد کنید تا لیست بیماران را بر اساس آن فیلتر کنید.

با تکمیل این مراحل، برنامه خود را با ارائه قابلیت جستجوی موثر بیماران با نام آنها به کاربران، ارتقا داده اید. این می تواند به طور قابل توجهی تجربه کاربر و کارایی در بازیابی داده ها را بهبود بخشد.

8. تبریک!

شما از کتابخانه موتور FHIR برای مدیریت منابع FHIR در برنامه خود استفاده کرده اید:

  • از Sync API برای همگام سازی منابع FHIR با سرور FHIR استفاده کنید
  • از Data Access API برای ایجاد، خواندن، به روز رسانی و حذف منابع محلی FHIR استفاده کنید
  • از Search API برای جستجوی منابع محلی FHIR استفاده کنید

آنچه را پوشش داده ایم

  • چگونه یک سرور محلی HAPI FHIR راه اندازی کنیم
  • نحوه آپلود داده های آزمایشی در سرور محلی HAPI FHIR
  • چگونه با استفاده از کتابخانه موتور FHIR یک برنامه اندروید بسازیم
  • نحوه استفاده از Sync API، Data Access API و Search API در کتابخانه موتور FHIR

مراحل بعدی

  • اسناد کتابخانه موتور FHIR را کاوش کنید
  • ویژگی های پیشرفته Search API را کاوش کنید
  • کتابخانه موتور FHIR را در برنامه اندروید خود اعمال کنید

بیشتر بدانید