An extension “extends” or enhances a FHIR resource or a data element in a custom way. The extension can be added to the root of a resource, such as “Patient.ethnicity” in US Core profile, and they can be added to individual elements such as HumanName, Address or Identifier.
Did you know that you can also add an extension to a primitive data type?
Primitives usually store a single item and are the most basic element in FHIR. For example: "Keren", false, 1234, 12/08/2024 etc.
For example, the patient resources might look like this:
The gender, birthDateor family elements are primitive elements, based on primitive datatypes.
How would you add an extension to the birthDate property or to the deceased property?
You will need to create a second attribute of the same name prefixed with an underscore, so the primitive extension for the birthDate property will be _birthdate.
The underscore tells FHIR that you’re accessing the underlying base Element for the primitive data type.
All the elements in FHIR inherit or descend from the base element. It contains two attributes: extension and id.
In the example below I added a “Time of year” extension to birthDate property and an “Is Alive” extension to the deceasedBoolean property.
There are several ways to create a FHIR resource, here is an example on how to add a primitive extension in each of the ways.
1. Using a Dynamic Object to build the FHIR resource
If you create the FHIR resource by using a dynamic object, you can just access the new primitive extension directly:
set resource = {}
set resource.resourceType = "Patient"do resource.%Set("active",1,"boolean")
set resource.gender = "female"set resource.birthDate = "1984-12-24"set resource."_birthDate" = {}
set resource."_birthDate".id = "123456"set resource."_birthDate".extension = []
set extension = {}
set extension.url = "http://example.org/fhir/StructureDefinition/Holiday"set extension.valueString = "Christmas"do resource."_birthDate".extension.%Push(extension)
write resource.toJson()
and this will be the result:
2. Using the HS.FHIR.DTL.VR4.Model.* classes
Also using the HS.FHIR.DTL.VR4.Model.* classes is not recommended, you'll have a primitiveExtension list in each level. You'll add your primitive extensions there, and than just reference your property to that extension index.
Here is a sample using the Data Transformation Builder:
and this is how you would do the same in code:
// Create a new patient resourceset resource=##class(HS.FHIR.DTL.vR4.Model.Resource.Patient).%New()
set resource.active=1set resource.gender="female"// cretate a new extensionset extension=##class(HS.FHIR.DTL.vR4.Model.Base.Extension).%New()
set extension.url="http://example.org/fhir/StructureDefinition/Holiday"set extension.valueString="Christmas"// Add the extension to the primitive extension listdo resource.primitiveExtension.Insert(extension)
// point the property to the extention index (#1 in this example)set resource.birthDate=$listbuild("1984-12-24",1)
write resource.ToJSON().Read()
Basically the property value is a $listbuild function that receives several parameters:
set resource.property = $listbuild(""original property value",<primitive extension index>,...)
The first parameter is the value for the original property - if you wish to omit the original property altogether, just send an empty string instead of a value.
The second parameter is the index number of the required primitive extension from the primitive extension list
if you wish to add several primitive extensions to the same property, just add them as well (after adding them first to the primitive extension list of course):
set resource.birthDate=$listbuild("1984-12-24",1,3,4,7)
3. Using the FHIR Object Model classes (from 2024.2)
If you are working in Iris for Health version 2024.2 and up, you might want to do the same using the new FHIR Object Model classes. in those classes the primitive extensions are already defined per each property that has it. So in our case, there is a birthDate property and a _birthDate property as well.
You can use the predefined structures to add a primitive extension:
#dim patient as HS.FHIRModel.R4.Patient
#dim extension as HS.FHIRModel.R4.Extension
set patient=##class(HS.FHIRModel.R4.Patient).%New()
set patient.gender="female"set patient.active=1set patient.birthDate="1984-12-24"// create a new elementset element=##class(HS.FHIRModel.R4.Element).%New()
do element.IncludeExtension()
// create a new extensionset extension=element.extension.MakeEntry()
set extension.url="http://example.org/fhir/StructureDefinition/Holiday"set extension.valueString="Christmas"// add the extension to the elementdo element.extension.add(extension)
// add the element to the resourceset patient."_birthDate"=element
write patient.toString()
In any way you wish to work, you can now create a primitive extension like a pro!
Look at the samples in the Open Exchange for all 3 ways:
O incrível Iris-nator chegou à cidade. Ele sabe o que você pensa, com apenas algumas perguntas ele é capaz de adivinhar o personagem em que você pensou. Você se atreve?
Alguns de vocês podem conhecer o jogo Akinator, onde um gênio é capaz de adivinhar o personagem em que você pensou, enquanto você responde “sim” ou “não” a uma pergunta simples.
Sem IA analisando suas redes sociais, sem microfones escutando... Então, como ele faz isso?
O segredo é um algoritmo simples e muitas pessoas jogando e alimentando o banco de dados.
Como funciona?
Vamos definir um termo: Nó.
Um nó pode ser uma pergunta ou o nome do personagem.
Se for uma pergunta, terá duas respostas: Sim ou Não.
Agora vamos dar um valor a ele.
À pergunta daremos o Id 1, à resposta afirmativa, daremos o Id 2 e à resposta negativa, o Id 3.
Agora vamos imaginar que ambas as respostas afirmativa e negativa retornam outra pergunta, com os personagens correspondentes para “sim” e “não”.
Podemos ver um padrão entre as perguntas e as respostas.
Respostas afirmativas são o dobro do identificador da pergunta, e respostas negativas são o dobro do identificador da pergunta mais um.
Então, se temos o nó n, o próximo nó a ser exibido será o nó n×2 se a resposta for "sim" ou o nó (n×2)+1 se a resposta for "não".
Vamos dar um exemplo:
Suponha que eu pense no Snoopy, e a pergunta seja "Seu personagem é fictício?", a resposta "sim" nos dirá que o personagem em que pensamos é o "Superman", mas não está correto.
Como transformamos nossa resposta em uma pergunta que nos leva ao Snoopy?
Precisamos de uma característica que nos diferencie do Superman, neste caso perguntaremos "Seu personagem é um cachorro?", então, a resposta afirmativa seria "Snoopy" e a resposta negativa seria "Superman".
Esta nova pergunta substituirá o Id do nó "Superman", o personagem "Snoopy" terá o dobro do nó da nova pergunta e o personagem "Superman" terá o dobro do nó da nova pergunta mais um.
Dessa forma, se criarmos muitas perguntas e respostas, nosso Iris-nator será capaz de adivinhar qualquer personagem em que você pensou.
Como o Iris-nator funciona?
Crie uma tabela com informações dos nós:
Class Irisnator.Data.Nodes Extends%Persistent
{
/// NodeIdProperty NodeId As%Numeric;/// Texto do nóProperty Text As%String(MAXLEN = "");/// Ttipo do nó (0 = texto, 1 = pergunta)Property Question As%Boolean [ InitialExpression = 0 ];/// Verbo da perguntaProperty Verb As%String(MAXLEN = "");
}
Observação: Por que existe um campo chamado "verbo"? Porque a pergunta é mostrada como {verbo} seu personagem {texto}? Portanto, é necessário saber qual é o verbo (é, tinha, faz, etc...).
O front-end foi criado com Angular 19. Para se comunicar com o IRIS, criei vários métodos de API:
GET localhost:52773/irisnator/api/node/:nodeId
Retorna as informações sobre o nó, e também o NodId para as respostas Sim e Não.
Quando o Iris-nator não consegue adivinhar seu personagem, preenchemos um formulário com os dados do novo personagem e qual seria a pergunta a fazer para diferenciá-lo do personagem a que ele chegou.
Então, movemos o personagem atual para a resposta "não" e colocamos o ID na nova pergunta.