Artículo
· 25 oct, 2023 Lectura de 6 min

Usando FHIR Adapter para ofrecer servicios FHIR sobre sistemas legacy - Guardando un Recurso

En el artículo anterior vimos cómo podíamos recuperar un recurso almacenado en la base de datos de nuestro HIS particular así que hoy veremos cómo podemos añadir nuevos registros en nuestro HIS cuyo origen es un recurso FHIR que recibamos en nuestro sistema.

Operaciones CRUD con FHIR

Una de las principales funcionalidades de FHIR es su soporte a las operaciones CRUD mediante API Rest, esto implica que cualquier sistema que trabaje con FHIR deberá proporcionar soporte a llamadas HTTP de tipo GET, POST, PUT y DELETE. Para nuestro artículo de hoy veremos como podemos tratar una llamada POST a nuestro endpoint configurado de forma automática al instalar FHIR Adapter.

Si revisamos las especificaciones de FHIR para las llamadas de almacenamiento de recursos veremos que nos indica que la URL con la que realizaremos la llamada deberá seguir este formato:

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

Para nuestro ejemplo no utilizaremos llamadas securizadas, así que quedará una URL tal que así:

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

Como lo que deseamos es grabar un nuevo paciente lo que deberemos realizar una llamada POST con los datos de nuestro paciente en el cuerpo de la llamada. En nuestro caso el formato de la llamada será application/fhir+json aunque podríamos utilizar application/fhir+xml sin ningún problema.

Registrando nuestro recurso "Patient"

En el artículo anterior ya pudimos ver la definición de los recursos Patient, por lo que no lo repetiremos aquí, lo que si vamos a ver es el como quedaría nuestro paciente de prueba formateado. Este será nuestro paciente:

{
    "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"
        }
    ]
}

Como podéis observar es un Resource de tipo Patient que será lo que enviemos desde nuestro Postman al endpoint de nuestro servidor:

Genial, hemos recibido un 200 y nuestro paciente se ha registrado en nuestro HIS, echemos un vistazo a como ha quedado nuestra tabla de Patient:

Ahí tenemos a Rebeca perfectamente archivada en nuestro HIS con el identificador que recibimos en la respuesta a nuestra petición POST. Vayamos ahora a nuestra producción para ver que camino ha recorrido nuestro mensaje FHIR dentro de IRIS.

Trabajando con el recurso Patient en IRIS

Hasta ahora hemos visto como podemos enviar un recurso FHIR hacia el endpoint de nuestro servidor, veamos como interpretamos el recurso FHIR recibido y lo transformamos para insertarlo en nuestro HIS particular.

Recordemos cómo tenemos configurada nuestra producción:

Nuestro mensaje llegará por InteropService y se reenviará a ProcessFHIRBP, donde se invocará FromAdapterToHIS para realizar la operación que corresponda. Veamos ahora la traza del mensaje recibido.

Aquí podemos ver los detalles del mensaje recibido, como podéis observar, hemos recibido la petición HTTP de tipo POST al endpoint Patient, también observamos que QuickStreamId tiene un valor, indicando que nuestro mensaje se encuentra contenido dentro de un Stream.

¿Qué va ha hacer nuestro BO con este mensaje?

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

  }

Muy sencillo, con la información disponible del request recibido podemos redirigir el mensaje al método adecuado, comprobamos que es una petición específica del recurso Patient y que el método ha sido POST, por lo tanto recuperaremos el Stream que almacena el mensaje y lo transformaremos a un %DynamicObject, a continuación lo trataremos desde el método InsertPatient, veamos el código de dicho método:

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
}

Bien, como podéis ver, lo primero que hacemos es ejecutar un insert sobre la tabla Patient de nuestro HIS (supondremos que alguien se ha asegurado previamente que no existe dicho paciente), con la inserción concluida ejecutaremos una SELECT sobre la misma tabla para obtener el identificador generado para dicho paciente y poder devolverlo a la aplicación cliente que nos lanzó la petición. Para completar el mensaje de respuesta podremos recuperar los campos que consideremos más relevantes.

Con los datos del paciente recuperados volveremos a nuestro BP el cual realizará las transformaciones necesarias para generar un recurso de tipo Patient que podamos retornar al cliente.

Podéis consultar la transformación en el artículo anterior.

Una vez generado el recurso lo transformaremos en un Stream que incluiremos en nuestro response y se lo retornaremos a la aplicación cliente:

Como podéis ver es fráncamente sencillo, sólo necesitamos recuperar los datos del recurso del paciente e insertarlos en su tabla correspondiente, finalmente retornaremos el objeto registrado del mismo modo que lo hicimos con la petición GET.

En el próximo artículo veremos como tratar un Bundle o conjunto de recursos. ¡Gracias por vuestra atención!

Comentarios (0)1
Inicie sesión o regístrese para continuar