記事
· 2024年5月28日 6m read

FHIR アダプターを使ってレガシーシステムに FHIR サービスを提供 - リソースの投稿編

前回の記事では特定の HIS のデータベースに格納されたリソースを取得する方法を確認したので、今回は、HIS に、システムで受け取る FHIR リソースを起点とする新しいレコードを追加する方法を説明します。

FHIR の CRUD 操作

FHIR の主な機能の 1 つに、Rest API による CRUD 操作のサポートがあります。つまり、FHIR と連携するすべてのシステムには、GET、POST、PUT、および DELETE タイプの HTTP 呼び出しがサポートされていなければなりません。 この記事では、FHIR アダプターをインストールした際に自動的に構成されたエンドポイントへの POST 呼び出しを処理する方法を見てみましょう。

FHIR のリソースストレージ呼び出しに関する仕様を確認すると、呼び出しに使用する URL は、以下のフォーマットを使用している必要があります。

http(s)://server_url/{endpoint}/{Resource}

この記事の例では、セキュリティで保護された呼び出しは行わないため、以下のような URL になります。

http://localhost:52774/Adapter/r4/Patient

ここで行いたいのは新しい患者を記録することであるため、呼び出しの本文に患者のデータを含めた POST 呼び出しを行う必要があります。 application/fhir+xml として問題なく XML 形式を使用することもできますが、この場合の呼び出しのフォーマットは application/fhir+json とします。

患者のリソースの保存

前回の記事ですでに Patient リソースの定義を確認したのでここでは繰り返しません。ここでは、整形済みのテスト患者がどのように見えるかを確認しましょう。 ここで見るのは以下の患者です。

{
    "resourceType": "Patient",
    "address": [
        {
            "city": "SALAMANCA",
            "line": [
                "CALLE LAMENTOS 2 1ºA"
            ],
            "postalCode": "45021"
        }
    ],
    "birthDate": "1988-01-23",
    "gender": "F",
    "identifier": [
        {
            "type": {
                "text": "NHC"
            },
            "value": "803987"
        },
        {
            "type": {
                "text": "DNI"
            },
            "value": "87654321F"
        }
    ],
    "name": [
        {
            "family": "SANZ LÓPEZ",
            "given": [
                "REBECA"
            ]
        }
    ],
    "telecom": [
        {
            "system": "phone",
            "value": "699850017"
        },
        {
            "system": "email",
            "value": "rebek1988@hotmail.com"
        }
    ]
}

ご覧のように、Postman からサーバーのエンドポイントに送信する Patient タイプの Resource です。

200 を受け取り、患者が HIS に登録されたので、Patient テーブルを確認しましょう。

ここに、POST リクエストに対するレスポンスで受け取った識別子で HIS に正しく記録された Rebecca があります。 では、本番環境にアクセスし、FHIR メッセージが IRIS 内で通過したパスを確認しましょう。

IRIS での Patient リソースの操作

ここまでで、FHIR リソースをサーバーのエンドポイントに送信する方法を見てきました。では、受け取った FHIR リソースをどのように解釈し、特定の HIS に挿入するために変換できるかを確認しましょう。

まず、本番環境の構成をもう一度確認しましょう。

メッセージは InteropService から届き、ProcessFHIRBP に転送されます。そこで、FromAdapterToHIS が呼び出され、対応する操作が実行されます。 では、受信したメッセージのトレースを確認しましょう。

ここでは、受信したメッセージの詳細を確認できます。ご覧のように、Patient エンドポイントに HTTP POST リクエストが届いており、QuickStreamId に値があることがわかります。メッセージは Stream に格納されていることが示されています。

BO はこのメッセージをどのように処理するのでしょうか?

elseif (requestData.Request.RequestPath [ "Patient")
  {
    if (requestData.Request.RequestMethod = "POST")
    {
      If requestData.QuickStreamId '= "" {
        Set quickStreamIn = ##class(HS.SDA3.QuickStream).%OpenId(requestData.QuickStreamId,, .tSC)
        
        set dynamicPatient = ##class(%DynamicAbstractObject).%FromJSON(quickStreamIn)

        set sc = ..InsertPatient(dynamicPatient, .response)
      }      
    }
    elseif (requestData.Request.RequestMethod = "GET")
    {
      set patientId = $Piece(requestData.Request.RequestPath,"/",2)
      set sc = ..GetPatient(patientId, .response)
    }

  }

非常に単純です。受信したリクエストから得られる情報をもって、メッセージを適切なメソッドにリダイレクトできます。Patient リソースからの特定のリクエストであることとメソッドが POST であることを確認できるため、メッセージを格納している Stream を取得してそれを %DynamicObject に変換します。以下では、InsertPatient メソッドからこれを処理します。そのメソッドのコードを見てみましょう。

Method InsertPatient(dynamicPatient As %DynamicAbstractObject, Output patient As Adapter.Message.FHIRResponse) As %Status
{
  Set tSC = $$$OK
  kill pResp
  set pResp=$$$NULLOREF
  set sqlInsert="INSERT INTO his.patient (name, lastname, phone, address, city, email, nhc, postal_code, birth_date, dni, gender) values (?,?,?,?,?,?,?,?,?,?,?)"
  //perform the Insert
  set tSC = ..Adapter.ExecuteUpdate(.nrows, sqlInsert, dynamicPatient.%Get("name").%Get(0).%Get("given").%Get(0), dynamicPatient.%Get("name").%Get(0).%Get("family"), dynamicPatient.%Get("telecom").%Get(0).value, 
    dynamicPatient.%Get("address").%Get(0).%Get("line").%Get(0), dynamicPatient.%Get("address").%Get(0).%Get("city"), dynamicPatient.%Get("telecom").%Get(1).value, dynamicPatient.%Get("identifier").%Get(1).value, 
    dynamicPatient.%Get("address").%Get(0).%Get("postalCode"), dynamicPatient.%Get("birthDate"), dynamicPatient.%Get("identifier").%Get(2).value, dynamicPatient.%Get("gender"))

  set sql="SELECT id, name, lastname, phone, address, city, email, nhc, postal_code, birth_date, dni, gender FROM his.patient WHERE nhc = ?"
  //perform the Select
  set tSC = ..Adapter.ExecuteQuery(.resultSet, sql, dynamicPatient.%Get("identifier").%Get(1).value)
  
  If resultSet.Next() {
    set personResult = {"id":(resultSet.GetData(1)), "name": (resultSet.GetData(2)), 
        "lastname": (resultSet.GetData(3)), "phone": (resultSet.GetData(4)), 
        "address": (resultSet.GetData(5)), "city": (resultSet.GetData(6)),
        "email": (resultSet.GetData(7)), "nhc": (resultSet.GetData(8)),
        "postalCode": (resultSet.GetData(9)), "birthDate": (resultSet.GetData(10)),
        "dni": (resultSet.GetData(11)), "gender": (resultSet.GetData(12)), "type": ("Patient")}
  } else {
    set personResult = {}
  }
  
  //create the response message
  do patient.Resource.Insert(personResult.%ToJSON())
    
    Return tSC
}

ご覧のように、最初に行うのは、HIS の Patient テーブルへの挿入です(誰かがその患者が存在しないことを確認済みであると仮定しましょう)。挿入が完了したら、この患者に対して生成された識別子を取得してリクエストを送信したクライアントアプリケーションにそれを返すために、同じテーブルで SELECT を実行します。 レスポンスメッセージを完成させるために、最も関連性があると思われるフィールドを取得できます。

取得した患者データとともに、クライアントに返すことのできる Patient タイプリソースを生成するために必要な変換を実行する BP に戻ります。

変換については、前の記事をご覧ください。

リソースが生成されたら、レスポンスに含めてクライアントアプリケーションに戻す Stream に変換します。

ご覧のように、非常に簡単です。患者リソースからデータを取得し、対応するテーブルに挿入するだけです。 最後に、登録されたオブジェクトを、GET リクエストで行ったのと同じ方法で返します。

次の記事では、Bundle またはリソースセットを処理する方法を説明します。 お読みいただきありがとうございました!

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください