• Imagine a seguinte cena: um médico e um desenvolvedor sentados lado a lado, olhando para os mesmos dados de um paciente. O médico precisa entender rapidamente o histórico clínico para tomar decisões. O desenvolvedor precisa processar essas informações em um sistema automatizado. Tradicionalmente, esses dois profissionais precisariam de representações completamente diferentes dos mesmos dados – uma interface gráfica amigável para o médico, e estruturas de dados complexas para o desenvolvedor.

    O FHIR (Fast Healthcare Interoperability Resources) quebra esse paradigma de forma elegante, pois foi projetado não apenas para permitir o processamento computacional dos dados, mas também para garantir que humanos em ambas as pontas da troca de informações consigam ter uma visão completa do que está acontecendo.

    Neste artigo, vamos explorar como o FHIR consegue essa façanha: ser simultaneamente compreensível para médicos que nunca viram uma linha de código e para desenvolvedores que precisam processar milhares de registros automaticamente.

    A Dualidade do FHIR: Máquina e Humano

    O grande diferencial do FHIR está em sua abordagem dual. Os Resources do FHIR são projetados para compartilhar dados de maneira computável – permitindo apoio à decisão, análise de tendências e processamento automatizado – mas também incluem uma narrativa legível por humanos que garante que pessoas possam compreender completamente o contexto clínico.

    Essa narrativa (chamada de “narrative” na especificação) deve existir para a maioria dos Resources. Em alguns casos, ela é gerada automaticamente a partir dos dados estruturados. Em outros, pode ser texto livre inserido diretamente por um profissional, como cartas de encaminhamento ou laudos de patologia.

    Resources como Formulários Universais

    Continuando com a metáfora apresentada na especificação oficial: pense nos Resources como formulários de papel. Cada tipo de informação clínica tem seu próprio formulário – um para alergias, um para prescrições, um para sinais vitais. Mas diferente de formulários tradicionais, os Resources do FHIR têm duas seções principais:

    1. A parte narrativa: Um resumo em linguagem natural, como se fosse anotado à mão
    2. A parte estruturada: Campos organizados que computadores podem processar

    Essa dupla representação é o que torna o FHIR único e poderoso.

    A Linguagem Comum: JSON e XML Legíveis

    O FHIR utiliza formatos amplamente conhecidos – JSON e XML – mas de uma forma especialmente legível. Os nomes dos campos são descritivos e intuitivos. Mesmo alguém sem conhecimento técnico profundo consegue identificar elementos como “name” (nome), “birthDate” (data de nascimento) ou “status” (status).

    Exemplo 1: Lendo Dados de um Paciente

    Vamos começar com um exemplo real de como os dados de um paciente aparecem no formato FHIR. Este é um Resource do tipo Patient:

    {
      "resourceType": "Patient",
      "id": "exemplo-paciente-001",
      "text": {
        "status": "generated",
        "div": "<div xmlns='http://www.w3.org/1999/xhtml'>
          <p><b>Maria Silva Santos</b> (nome social: Maria Santos)</p>
          <p>Identificação: CPF 123.456.789-00</p>
          <p>Telefone: (85) 98765-4321 (celular)</p>
          <p>Sexo: Feminino | Data de nascimento: 15/03/1985 (39 anos)</p>
          <p>Endereço: Rua das Flores, 123, Apto 45 - Centro, Fortaleza, CE, 60000-000</p>
        </div>"
      },
      "identifier": [
        {
          "type": {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                "code": "TAX",
                "display": "CPF"
              }
            ]
          },
          "value": "12345678900"
        }
      ],
      "name": [
        {
          "use": "official",
          "family": "Silva Santos",
          "given": ["Maria"]
        },
        {
          "use": "usual",
          "family": "Santos",
          "given": ["Maria"]
        }
      ],
      "telecom": [
        {
          "system": "phone",
          "value": "(85) 98765-4321",
          "use": "mobile"
        }
      ],
      "gender": "female",
      "birthDate": "1985-03-15",
      "address": [
        {
          "use": "home",
          "type": "physical",
          "line": ["Rua das Flores, 123, Apto 45"],
          "city": "Fortaleza",
          "state": "CE",
          "postalCode": "60000-000",
          "country": "BR"
        }
      ]
    }

    Como um médico lê isso:

    Se esse médico receber apenas esses dados (sem uma interface gráfica), ele pode imediatamente olhar para a seção text e encontrar um resumo formatado e legível: “Maria Silva Santos, CPF 123.456.789-00, 39 anos, feminino, residente em Fortaleza”. Todas as informações essenciais estão ali, em português claro, sem necessidade de entender estruturas de dados.

    Como um desenvolvedor lê isso:

    O desenvolvedor olha para os mesmos dados e vê estrutura: o campo gender pode alimentar estatísticas demográficas, birthDate permite cálculos de idade automatizados, identifier possibilita buscar outros registros desse paciente em diferentes sistemas. Os dados estão padronizados e prontos para processamento.

    A mágica: Ambos estão olhando para exatamente o mesmo arquivo. Não há tradução necessária.

    Exemplo 2: Compreendendo Resultados de Exames

    Agora vejamos um exemplo mais complexo: resultados de exames laboratoriais. Este é um Resource do tipo Observation:

    {
      "resourceType": "Observation",
      "id": "hemoglobina-glicada-001",
      "text": {
        "status": "generated",
        "div": "<div xmlns='http://www.w3.org/1999/xhtml'>
          <p><b>Hemoglobina Glicada (HbA1c)</b></p>
          <p>Paciente: Maria Silva Santos</p>
          <p>Data da coleta: 10 de outubro de 2025</p>
          <p>Resultado: <b>7.8%</b></p>
          <p>Valor de referência: 4.0 - 6.0% (Normal)</p>
          <p><b>Interpretação: ACIMA DO VALOR DE REFERÊNCIA</b></p>
          <p>Observação: Resultado sugere controle glicêmico inadequado. 
             Avaliar ajuste terapêutico.</p>
        </div>"
      },
      "status": "final",
      "category": [
        {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/observation-category",
              "code": "laboratory",
              "display": "Laboratory"
            }
          ]
        }
      ],
      "code": {
        "coding": [
          {
            "system": "http://loinc.org",
            "code": "4548-4",
            "display": "Hemoglobin A1c/Hemoglobin.total in Blood"
          }
        ],
        "text": "Hemoglobina Glicada"
      },
      "subject": {
        "reference": "Patient/exemplo-paciente-001",
        "display": "Maria Silva Santos"
      },
      "effectiveDateTime": "2025-10-10T08:30:00-03:00",
      "issued": "2025-10-10T14:20:00-03:00",
      "valueQuantity": {
        "value": 7.8,
        "unit": "%",
        "system": "http://unitsofmeasure.org",
        "code": "%"
      },
      "interpretation": [
        {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
              "code": "H",
              "display": "High"
            }
          ],
          "text": "Acima do valor de referência"
        }
      ],
      "referenceRange": [
        {
          "low": {
            "value": 4.0,
            "unit": "%"
          },
          "high": {
            "value": 6.0,
            "unit": "%"
          },
          "text": "Faixa normal para adultos não diabéticos"
        }
      ],
      "note": [
        {
          "text": "Resultado sugere controle glicêmico inadequado. Avaliar ajuste terapêutico."
        }
      ]
    }

    Perspectiva do médico:

    Ao abrir esse arquivo, o médico vai direto à seção narrativa e lê: “Hemoglobina Glicada de 7.8%, acima do valor de referência (4.0-6.0%), resultado sugere controle glicêmico inadequado”. Ele tem todas as informações clínicas relevantes para tomar uma decisão, incluindo a interpretação e a recomendação.

    Perspectiva do desenvolvedor:

    O desenvolvedor vê que valueQuantity.value contém 7.8, interpretation indica “H” (High), e code.coding usa LOINC “4548-4” – um código padronizado internacionalmente. Isso permite que o sistema:

    • Compare automaticamente com valores de referência
    • Agrupe todos os exames de HbA1c do paciente ao longo do tempo
    • Acione alertas se valores estiverem críticos
    • Gere gráficos de evolução

    A convergência: Quando médico e desenvolvedor discutem esse caso, ambos podem referenciar os mesmos elementos. O médico pode dizer “o valor está em 7.8%” e o desenvolvedor sabe exatamente onde encontrar isso nos dados. O desenvolvedor pode mencionar “o código LOINC 4548-4” e o médico, mesmo sem conhecer LOINC profundamente, vê na narrativa que é Hemoglobina Glicada.

    Exemplo 3: Prescrição Médica

    Vejamos como uma prescrição se parece no FHIR, usando o Resource MedicationRequest:

    {
      "resourceType": "MedicationRequest",
      "id": "prescricao-metformina-001",
      "text": {
        "status": "generated",
        "div": "<div xmlns='http://www.w3.org/1999/xhtml'>
          <p><b>Prescrição de Medicamento</b></p>
          <p>Paciente: Maria Silva Santos</p>
          <p>Medicamento: <b>Metformina 850mg - comprimidos</b></p>
          <p>Posologia: Tomar 1 comprimido por via oral, 2 vezes ao dia, 
             durante as refeições (café da manhã e jantar)</p>
          <p>Quantidade: 60 comprimidos</p>
          <p>Refil: Permitido 3 refis</p>
          <p>Prescritor: Dr. João Oliveira (CRM-CE 12345)</p>
          <p>Data: 10 de outubro de 2025</p>
          <p>Justificativa: Controle de diabetes mellitus tipo 2 com 
             HbA1c elevada (7.8%)</p>
        </div>"
      },
      "status": "active",
      "intent": "order",
      "medicationCodeableConcept": {
        "coding": [
          {
            "system": "http://www.whocc.no/atc",
            "code": "A10BA02",
            "display": "Metformin"
          }
        ],
        "text": "Metformina 850mg"
      },
      "subject": {
        "reference": "Patient/exemplo-paciente-001",
        "display": "Maria Silva Santos"
      },
      "authoredOn": "2025-10-10T14:30:00-03:00",
      "requester": {
        "reference": "Practitioner/medico-joao-001",
        "display": "Dr. João Oliveira (CRM-CE 12345)"
      },
      "reasonCode": [
        {
          "text": "Diabetes mellitus tipo 2 com controle glicêmico inadequado"
        }
      ],
      "dosageInstruction": [
        {
          "sequence": 1,
          "text": "Tomar 1 comprimido por via oral, 2 vezes ao dia, durante as refeições",
          "timing": {
            "repeat": {
              "frequency": 2,
              "period": 1,
              "periodUnit": "d"
            }
          },
          "route": {
            "coding": [
              {
                "system": "http://snomed.info/sct",
                "code": "26643006",
                "display": "Oral route"
              }
            ]
          },
          "doseAndRate": [
            {
              "doseQuantity": {
                "value": 1,
                "unit": "comprimido",
                "system": "http://unitsofmeasure.org"
              }
            }
          ]
        }
      ],
      "dispenseRequest": {
        "numberOfRepeatsAllowed": 3,
        "quantity": {
          "value": 60,
          "unit": "comprimido"
        },
        "expectedSupplyDuration": {
          "value": 30,
          "unit": "dias"
        }
      }
    }

    Como o médico interpreta:

    Lendo a narrativa, o médico vê imediatamente: “Prescrição de Metformina 850mg, 1 comprimido 2x ao dia durante refeições, para Maria Silva Santos, com justificativa de diabetes com HbA1c elevada”. É como ler uma receita tradicional, mas em formato digital.

    Como o farmacêutico processa:

    O farmacêutico (que também não é programador) consegue ver todas as informações necessárias para dispensação: quantidade (60 comprimidos), número de refis (3), posologia clara. Não precisa de sistema especial para entender.

    Como o sistema automatiza:

    O sistema de farmácia pode automaticamente:

    • Verificar interações medicamentosas usando o código ATC “A10BA02”
    • Validar se a quantidade prescrita está adequada à posologia (60 comprimidos para 30 dias, 2x ao dia = correto)
    • Alertar quando os refis estiverem esgotados
    • Conectar a prescrição ao diagnóstico do paciente

    A comunicação fluida: Durante uma discussão sobre o caso, o médico, o farmacêutico e o desenvolvedor do sistema podem todos referenciar esses mesmos dados. O médico fala “prescrevi 2x ao dia”, o farmacêutico confirma, e o desenvolvedor sabe que isso está em dosageInstruction.timing.repeat.

    A Ponte da Compreensão Mútua

    O que torna o FHIR especial não é apenas ter dados estruturados ou apenas ter texto legível – é ter ambos, juntos, no mesmo lugar. Como explica a especificação oficial, a narrativa é esperada para a maioria dos Resources, podendo ser omitida apenas em circunstâncias limitadas.

    Isso cria um ambiente onde:

    Médicos podem auditar sistemas: Se um médico desconfia que o sistema interpretou algo incorretamente, ele pode olhar os dados brutos e verificar. Não há “caixa preta”.

    Desenvolvedores entendem o contexto clínico: Ao ver a narrativa junto com os dados estruturados, desenvolvedores compreendem o significado clínico real do que estão processando.

    Reguladores podem fiscalizar: Auditores e reguladores podem verificar tanto a precisão técnica (dados estruturados) quanto a clareza clínica (narrativa) sem precisar de ferramentas especializadas.

    Pacientes podem compreender seus dados: Com acesso crescente aos próprios registros médicos, pacientes podem ler a narrativa e entender o que está documentado sobre sua saúde.

    Conclusão

    O FHIR resolve um problema fundamental que existia há décadas na área de saúde: a desconexão entre a representação de dados para humanos e para máquinas. Ao unir narrativa legível e estrutura processável no mesmo artefato, o padrão cria uma linguagem comum que técnicos e não-técnicos podem compartilhar.

    Principais benefícios dessa abordagem:

    • Transparência total: Não há informações “escondidas” em formatos proprietários
    • Redução de erros de interpretação: Todos veem os mesmos dados da mesma fonte
    • Facilita colaboração: Médicos e desenvolvedores podem discutir casos específicos usando a mesma referência
    • Empoderamento do paciente: Dados de saúde tornam-se compreensíveis para quem mais importa
    • Auditabilidade: Processos de conformidade e qualidade podem verificar tanto aspectos técnicos quanto clínicos

    Considerações importantes:

    • A narrativa é essencial: Implementações que negligenciam a parte narrativa perdem grande parte do valor do FHIR
    • Contexto cultural: Narrativas devem ser localizadas adequadamente para cada idioma e contexto
    • Equilíbrio entre automação e compreensão: O ideal é que narrativas sejam geradas automaticamente quando possível, mas permitam enriquecimento manual quando necessário

    O verdadeiro poder do FHIR não está apenas em ser um padrão técnico robusto – está em ser uma ponte de comunicação entre mundos que historicamente falavam línguas diferentes. Quando um médico e um desenvolvedor podem sentar lado a lado, olhar para os mesmos dados JSON, e ambos entenderem o que estão vendo – cada um em seu próprio nível de profundidade – algo fundamental mudou no ecossistema de saúde digital.

    Para explorar mais sobre FHIR, recomendo começar pelos Resources mais comuns (Patient, Observation, MedicationRequest) disponíveis na especificação oficial, sempre observando como a narrativa e os dados estruturados trabalham juntos para criar essa compreensão universal.

    Referências

    1. HL7 FHIR Specification v5.0.0 – FHIR Overview – Clinicians. Disponível em: https://www.hl7.org/fhir/overview-clinical.html
    2. HL7 FHIR Specification v5.0.0 – FHIR Overview. Disponível em: https://www.hl7.org/fhir/overview.html
    3. HL7 FHIR Specification v5.0.0 – Narrative Documentation. Disponível em: https://www.hl7.org/fhir/narrative.html
  • Se você já tentou integrar sistemas de saúde diferentes, sabe que pode ser um verdadeiro pesadelo. Cada sistema tem seu próprio formato de dados, sua própria maneira de representar um paciente, um diagnóstico ou uma prescrição médica. É como tentar encaixar peças de quebra-cabeças completamente diferentes.

    Mas e se existisse uma forma padronizada e moderna de trocar informações de saúde? É aqui que entra o FHIR (Fast Healthcare Interoperability Resources, pronunciado “fire” 🔥). O FHIR é um padrão para troca eletrônica de informações de saúde, projetado para ser simples de implementar sem sacrificar a integridade das informações.

    Neste artigo, vamos explorar como o FHIR funciona, seus conceitos fundamentais e, principalmente, como você pode começar a desenvolver APIs de saúde usando esse padrão. Se você trabalha com integração de sistemas de saúde ou está curioso sobre o assunto, este guia é para você.

    O que é FHIR?

    1. Um padrão moderno de interoperabilidade em saúde

    FHIR (Fast Healthcare Interoperability Resources) é uma especificação técnica desenvolvida pela HL7 que define como sistemas de saúde devem estruturar, representar e trocar informações eletronicamente.

    O FHIR foi projetado para simplificar a implementação sem sacrificar a integridade da informação, combinando as melhores práticas da web moderna com mais de 20 anos de experiência da HL7 em modelagem de dados clínicos. Na prática, isso significa que você pode consumir uma API FHIR da mesma forma que consome qualquer API REST contemporânea – com verbos HTTP padrão, endpoints intuitivos e respostas em JSON.

    2. Arquitetura baseada em Resources

    Um conjunto fixo de elementos de dados (resourceType, id, meta) Elementos específicos do tipo (ex: Patient tem name, gender, birthDate) Suporte a extensões para campos customizados Referências para outros Resources (relacionamentos entre entidades)

    Pense nos Resources como DTOs (Data Transfer Objects) versionados e autocontidos, onde cada tipo tem sua própria especificação formal que define estrutura, cardinalidade, tipos de dados e terminologias permitidas.

    2.1 Anatomia de um Resource

    Todo Resource FHIR compartilha características comuns:

    1. Um identificador único: Geralmente uma URL que define onde o recurso pode ser encontrado
    2. Metadados comuns: Informações sobre versão, data de última atualização, etc.
    3. Uma narrativa legível por humanos: Resumo em XHTML do conteúdo
    4. Elementos de dados definidos: Um conjunto específico para cada tipo de recurso
    5. Framework de extensibilidade: Para suportar variações necessárias
    2.2 Extensibilidade: Adaptando às Suas Necessidades

    Sempre haverão cenários de necessidade específica, para isso o FHIR possui o mecanismo Extensions que permite adicionar campos customizados sem quebrar a compatibilidade.

    Atualmente, a especificação define 157 tipos diferentes de recursos, cobrindo desde informações clínicas básicas (como Patient, Observation) até processos complexos (como CarePlan, MedicationRequest).

    Representação dos Dados

    Os recursos podem ser representados em três formatos: JSONXML ou RDF. Veja um exemplo simplificado de um paciente em JSON:

    {
      "resourceType": "Patient",
      "id": "123",
      "identifier": [{
        "system": "http://hospital.exemplo.com/pacientes",
        "value": "987654"
      }],
      "name": [{
        "family": "Silva",
        "given": ["João", "Pedro"]
      }],
      "gender": "male",
      "birthDate": "1985-03-15"
    }

    A API RESTful do FHIR

    Uma das grandes vantagens do FHIR é que ele adota práticas RESTful modernas que desenvolvedores já conhecem. Como explicado na documentação para desenvolvedores, o FHIR “fornece uma API REST com um conjunto rico, mas simples, de interações”.

    As operações principais seguem os verbos HTTP padrão:

    • POST /base/{resourceType} – Criar um recurso
    • GET /base/{resourceType}/{id} – Ler um recurso específico
    • PUT /base/{resourceType}/{id} – Atualizar um recurso
    • DELETE /base/{resourceType}/{id} – Deletar um recurso
    • GET /base/{resourceType}?parametros – Buscar recursos

    Criando um Paciente

    Segundo a especificação, para criar um recurso você envia uma requisição HTTP POST para o endpoint do tipo de recurso. Veja como criar um novo paciente:

    Requisição:

    POST /fhir/Patient HTTP/1.1
    Host: servidor.exemplo.com
    Content-Type: application/fhir+json
    Accept: application/fhir+json
    
    {
      "resourceType": "Patient",
      "identifier": [{
        "system": "http://hospital.exemplo.com/pacientes",
        "value": "987654"
      }],
      "name": [{
        "family": "Silva",
        "given": ["João", "Pedro"]
      }],
      "gender": "male",
      "birthDate": "1985-03-15",
      "active": true
    }

    Resposta:

    HTTP/1.1 201 Created
    Location: http://servidor.exemplo.com/fhir/Patient/347
    ETag: W/"1"
    Content-Type: application/fhir+json
    
    {
      "resourceType": "OperationOutcome",
      "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Operação realizada com sucesso</div>"
      }
    }

    Note que o servidor retorna um código 201 Created e o cabeçalho Location indica onde o recurso foi criado, com o ID atribuído pelo servidor (347 neste caso).

    Buscando um Paciente específico

    A leitura é feita através de uma requisição GET simples:

    Requisição:

    GET /fhir/Patient/347 HTTP/1.1
    Host: servidor.exemplo.com
    Accept: application/fhir+json

    Resposta:

    HTTP/1.1 200 OK
    Content-Type: application/fhir+json
    ETag: W/"1"
    Last-Modified: Mon, 18 Aug 2014 15:43:30 GMT
    
    {
      "resourceType": "Patient",
      "id": "347",
      "meta": {
        "versionId": "1",
        "lastUpdated": "2014-08-18T15:43:30Z"
      },
      "identifier": [{
        "system": "http://hospital.exemplo.com/pacientes",
        "value": "987654"
      }],
      "name": [{
        "family": "Silva",
        "given": ["João", "Pedro"]
      }],
      "gender": "male",
      "birthDate": "1985-03-15",
      "active": true
    }

    Buscando pacientes por parâmetros

    A busca é uma das operações mais poderosas do FHIR. Você pode encontrar recursos usando diversos critérios através de parâmetros na URL:

    Requisição – Buscar pacientes por nome de família:

    GET /fhir/Patient?family=Silva HTTP/1.1
    Host: servidor.exemplo.com
    Accept: application/fhir+json

    Resposta:

    HTTP/1.1 200 OK
    Content-Type: application/fhir+json
    
    {
      "resourceType": "Bundle",
      "type": "searchset",
      "total": 2,
      "link": [{
        "relation": "self",
        "url": "http://servidor.exemplo.com/fhir/Patient?family=Silva"
      }],
      "entry": [{
        "fullUrl": "http://servidor.exemplo.com/fhir/Patient/347",
        "resource": {
          "resourceType": "Patient",
          "id": "347",
          "name": [{
            "family": "Silva",
            "given": ["João", "Pedro"]
          }],
          "gender": "male",
          "birthDate": "1985-03-15"
        }
      }, {
        "fullUrl": "http://servidor.exemplo.com/fhir/Patient/891",
        "resource": {
          "resourceType": "Patient",
          "id": "891",
          "name": [{
            "family": "Silva",
            "given": ["Maria"]
          }],
          "gender": "female",
          "birthDate": "1992-07-22"
        }
      }]
    }

    Como explicado na especificação, “o resultado de uma busca é sempre um bundle do tipo ‘searchset’” – uma coleção de recursos que correspondem aos critérios.

    Busca com Múltiplos Parâmetros

    Você pode combinar vários critérios de busca:

    Requisição – Buscar prescrições de um paciente específico:

    GET /fhir/MedicationRequest?patient=347&status=active HTTP/1.1
    Host: servidor.exemplo.com
    Accept: application/fhir+json

    Atualizando Paciente

    Para atualizar um recurso você envia uma requisição HTTP PUT para o endpoint do tipo de recurso.

    Requisição:

    PUT /fhir/Patient/347 HTTP/1.1
    Host: servidor.exemplo.com
    Content-Type: application/fhir+json
    
    {
      "resourceType": "Patient",
      "id": "347",
      "meta": {
        "versionId": "1"
      },
      "identifier": [{
        "system": "http://hospital.exemplo.com/pacientes",
        "value": "987654"
      }],
      "name": [{
        "family": "Silva",
        "given": ["João", "Pedro"]
      }],
      "gender": "male",
      "birthDate": "1985-03-15",
      "active": true,
      "telecom": [{
        "system": "phone",
        "value": "(85) 98765-4321",
        "use": "mobile"
      }]
    }

    Resposta:

    HTTP/1.1 200 OK
    Location: http://servidor.exemplo.com/fhir/Patient/347/_history/2
    ETag: W/"2"
    Content-Type: application/fhir+json
    
    {
      "resourceType": "OperationOutcome",
      "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Recurso atualizado com sucesso</div>"
      }
    }

    Removendo um Paciente

    Requisição:

    DELETE /fhir/Patient/347 HTTP/1.1
    Host: servidor.exemplo.com

    Resposta:

    HTTP/1.1 204 No Content

    Conclusão

    O HL7 FHIR representa uma mudança de paradigma no desenvolvimento de sistemas de saúde interoperáveis. Ao adotar padrões RESTful modernos e fornecer recursos bem definidos, ele simplifica drasticamente a integração entre sistemas diferentes.

    Principais benefícios:

    • Facilidade de implementação: API REST padrão, sem necessidade de bibliotecas especializadas
    • Agnóstico à tecnologia: Funciona com qualquer linguagem que suporte HTTP
    • Flexibilidade: Extensões permitem adaptação a necessidades específicas
    • Padrão maduro: Baseado em décadas de experiência do HL7
    • Ampla adoção: Crescente suporte de fornecedores e instituições

    Trade-offs a considerar:

    • Curva de aprendizado inicial para entender a especificação
    • Necessidade de compreender o domínio de saúde além da parte técnica
    • Complexidade em cenários muito específicos pode exigir extensões

    Próximos passos:

    1. Explore a documentação oficial do FHIR
    2. Experimente com um servidor público como o HAPI FHIR para testar requisições
    3. Comece com recursos simples (Patient, Observation) antes de avançar
    4. Use ferramentas como Postman ou cURL para experimentar com a API
    5. Participe da comunidade FHIR para aprender com outros desenvolvedores

    O FHIR está transformando a forma como sistemas de saúde se comunicam. Como você viu, trabalhar com FHIR é tão simples quanto fazer requisições HTTP REST – uma habilidade que praticamente todo desenvolvedor já possui. Se você trabalha nessa área, este é definitivamente um padrão que vale a pena dominar.

    Referências

    HL7 International. Official FHIR website: http://www.hl7.org

    HL7 FHIR Specification v5.0.0 – FHIR Overview. Disponível em: http://hl7.org/fhir/overview.html

    HL7 FHIR Specification v5.0.0 – FHIR Overview for Developers. Disponível em: http://hl7.org/fhir/overview-dev.html

  • Os testes unitários são escritos com o objetivo de obter maior qualidade na entrega de um software e facilidade em sua manutenção. Porém, se após alguma modificação um teste falhar, e esse estiver mal escrito, o desenvolvedor terá dois problemas: O código que agora não funciona como deveria e por isso o teste falhou e o próprio teste que está de difícil de ser compreendido.

    Por isso, não basta construir testes unitários, é necessário construir testes unitários de qualidade.

    Um código de qualidade requer organização e quando se fala de organização de teste unitário um padrão muito adotado é o Triple A ou AAA. Esse padrão prega que devemos estruturar os nossos testes em 3 passos: Arrange, Act e Assert (AAA).

    Arrange

    Nesse passo deve ser estruturado todo o cenário para a execução do teste, é onde serão criados os objetos que serão passados como parâmetro na função ou método a ser testado.

    Exemplo: Em caso de estarmos testando uma função ou método de cadastro de produto, que recebe como parâmetro um objeto produto, é neste momento que faremos a criação desse objeto.

    Em caso de uso de mocks, é neste passo que eles devem ser definidos.

    Act

    Nesse passo deve ser realizada a execução do teste em si, é onde será a acionada a função ou o método a ser testado.

    Exemplo: Seguindo o mesmo exemplo, é agora que acionaremos o método responsável por realizar o cadastro do produto passando como parâmetro o objeto criado no passo anterior.

    Assert

    No ultimo passo deve ser verificado se o resultado do teste está de acordo com o que é esperado.

    Exemplo: Agora verificaremos se o código do novo produto foi retornado, ou seja, se o produto foi criado efetivamente.

    Em caso de uso de mocks, é nesse passo que deve ser verificado se todos os métodos ou funções que seriam acionados, ou não, foram invocados.

    Esse padrão pode parecer algo muito intuitivo, mas acredite existem diversos testes unitários criados por aí que ainda no passo de Arrange já realizam verificações, obviamente em cenários de teste complexos que não é o caso do nosso exemplo.

    Com a adoção desse padrão de organização conseguimos garantir que os nossos testes estarão estruturados de forma organizada para facilitar o entendimento de outros desenvolvedores em futuras manutenções.

    Espero ter conseguido te ajudar!

    Caso você ainda não tenha visto, tenho outro artigo falando da importância da adoção de um padrão para definição do nome dos testes unitários: https://hyagodev.medium.com/boas-pr%C3%A1ticas-de-testes-unit%C3%A1rios-n%C3%A3o-cometa-o-erro-de-descrever-o-seu-teste-dessa-forma-e6be33b2f4bb

    Até a próxima, abraços!

  • Você pode até achar que não tem muita relevância, mas eu te garanto que, após um tempo definindo seus testes dessa forma, você terá um grande problema!

    Na construção de testes unitários, o padrão de nomenclatura é tão importante quanto a qualidade de escrita do código de teste. Os testes devem ter nomes claros e objetivos, especificando o que está sendo testado, como está sendo testado e qual é o resultado esperado.

    Imagine que você está trabalhando em um projeto de construção de um CRUD simples, que possui poucos testes unitários, e o cenário de criação inclui testes nomeados como:

    • criarProdutoSucesso
    • criarProdutoErro

      Acredite, eu já vi diversos projetos que têm seus testes unitários descritos dessa forma.

      Digamos que, no cenário de cadastro, exista uma regra que proíbe o cadastro de produtos com o mesmo nome, e isso está sendo garantido pelo teste criarProdutoErro. Amanhã, poderá surgir outra regra para a operação de cadastro, e você terá que implementar outro teste unitário. Agora, haverá um novo requisito que não permitirá cadastrar um produto sem categoria. Seguindo a mesma lógica, o teste provavelmente será nomeado como criarProdutoSemCategoria.

      Porém, essa nomenclatura pode gerar confusão. No teste, seu objetivo é garantir que nenhum novo produto seja criado sem categoria. Vamos analisar duas hipóteses:

      • Falha no teste criarProdutoSemCategoria: Um desenvolvedor que não criou esse teste poderá imaginar que DEVE ser permitido criar produtos sem categoria, mas não é isso que deve acontecer. Então, ele irá modificar o código para permitir a criação de um produto sem categoria.
      • Sucesso no teste criarProdutoSemCategoria: Um desenvolvedor que sabe da regra que proíbe o cadastro de um produto sem categoria, mas que não conhece o código do teste, poderá entender que existe uma falha, na qual a regra que deveria impedir o cadastro de um produto sem categoria não está funcionando.

      Como você pode ver, um nome de teste unitário mal definido pode causar bastante confusão. Para evitar esses problemas, sugiro o uso de um padrão bem conhecido: [nome_metodo_ou_funcao]_[descricao_cenario]_[resultado_esperado].

      Usando o mesmo exemplo anterior, em que não é possível criar um produto sem categoria, vamos refazer a nomenclatura dos testes seguindo o padrão:

      • criarProduto_QuandoAcionarCriacaoDeProdutoSemCategoria_LevantarExcecao
      • criarProduto_QuandoAcionarCriacaoDeProdutoDeNomeJaExistente_LevantarExcecao
      • criarProduto_QuandoAcionarCriacaoDeProdutoComDadosValidos_RetornarProdutoCadastrado

      Você consegue notar a diferença? Agora, em caso de falhas, o desenvolvedor, conhecendo a regra ou não, saberá o que está sendo testado e qual o resultado esperado.

      Ao longo do tempo, todas as aplicações tendem a crescer em número de testes unitários, seja com novas funcionalidades ou com bugs descobertos. Já pensou o tamanho do problema que será criado ao longo do tempo pelo simples fato de não ter um padrão de nomenclatura de testes que seja claro e objetivo?!

      Espero ter contribuído com você para uma melhor escrita de testes.

      Até a próxima, abraços!