Saltar al contenido

Inicio Rápido

Esta guía demuestra las operaciones más comunes: crear un recurso, serializarlo a JSON y deserializarlo de vuelta. Todos los ejemplos usan el paquete R4, pero la API es idéntica para R4B y R5.

1. Crear un Patient con un Literal de Struct

La forma más directa de crear un recurso FHIR es inicializando los campos del struct. Los campos FHIR opcionales se representan como punteros Go, por lo que necesitas una función auxiliar o el operador de dirección para establecerlos.

package main

import (
    "fmt"

    "github.com/gofhir/models/r4/v2"
)

// ptrTo is a generic helper that returns a pointer to the given value.
func ptrTo[T any](v T) *T {
    return &v
}

func main() {
    patient := r4.Patient{
        Id:           ptrTo("123"),
        Active:       ptrTo(true),
        Name: []r4.HumanName{
            {Family: ptrTo("Smith"), Given: r4.PtrSlice("John")},
        },
    }

    data, _ := r4.Marshal(&patient)
    fmt.Println(string(data))
}

Salida:

{"resourceType":"Patient","id":"123","active":true,"name":[{"family":"Smith","given":["John"]}]}

2. Crear un Patient con el Builder

El builder elimina el código repetitivo de punteros: Set* recibe un valor simple para los campos únicos y Add* añade a los repetibles, envolviendo el puntero internamente.

patient := r4.NewPatientBuilder().
    SetId("patient-123").
    SetActive(true).
    SetGender(r4.AdministrativeGenderMale).
    SetBirthDate("1990-01-15").
    Build()

También puedes agregar campos anidados complejos como nombres e identificadores:

use := r4.NameUseOfficial
family := "Smith"

patient := r4.NewPatientBuilder().
    SetId("patient-456").
    AddName(r4.HumanName{
        Use:    &use,
        Family: &family,
        Given:  r4.PtrSlice("John"),
    }).
    AddIdentifier(r4.Identifier{
        System: ptrTo("http://hospital.example.org/mrn"),
        Value:  ptrTo("12345"),
    }).
    Build()

3. Crear un Patient con el Builder Fluido

El patrón builder proporciona una API encadenable. Comienza con New<Resource>Builder(), establece campos con métodos Set y Add, y finaliza con .Build().

family := "Garcia"
use := r4.NameUseOfficial

patient := r4.NewPatientBuilder().
    SetId("patient-789").
    SetActive(true).
    SetGender(r4.AdministrativeGenderFemale).
    SetBirthDate("1985-06-20").
    AddName(r4.HumanName{
        Use:    &use,
        Family: &family,
        Given:  r4.PtrSlice("Maria"),
    }).
    Build()

4. Serializar a JSON

Usa r4.Marshal en lugar de json.Marshal. La función de la biblioteca deshabilita el escapado HTML para que el XHTML narrativo de FHIR en los campos text.div se preserve correctamente. El campo resourceType siempre se inyecta automáticamente.

data, err := r4.Marshal(patient)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(data))

Para una salida con formato legible, usa MarshalIndent:

data, err := r4.MarshalIndent(patient, "", "  ")
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(data))

Salida:

{
  "resourceType": "Patient",
  "id": "patient-789",
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Garcia",
      "given": ["Maria"]
    }
  ],
  "gender": "female",
  "birthDate": "1985-06-20"
}

5. Deserializar desde JSON

Tipo de Recurso Conocido

Si conoces el tipo de recurso en tiempo de compilación, deserializa directamente en el struct:

var patient r4.Patient
err := json.Unmarshal(data, &patient)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Patient ID: %s\n", *patient.Id)

Tipo de Recurso Desconocido

Cuando el tipo de recurso no se conoce de antemano (por ejemplo, al leer una respuesta de un servidor FHIR), usa UnmarshalResource. Esta función inspecciona el campo resourceType y devuelve el struct Go correcto detrás de la interfaz Resource:

resource, err := r4.UnmarshalResource(data)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Type: %s\n", resource.GetResourceType())

// Type-assert to access resource-specific fields
if patient, ok := resource.(*r4.Patient); ok {
    fmt.Printf("Patient ID: %s\n", *patient.Id)
}

También puedes consultar el tipo de recurso sin una deserialización completa:

resourceType, err := r4.GetResourceType(data)
if err != nil {
    log.Fatal(err)
}
fmt.Println(resourceType) // "Patient"

6. Crear una Observation

Aquí hay un ejemplo más completo que muestra una Observation con un código, valor y categoría:

codeSystem := "http://loinc.org"
codeCode := "8867-4"
codeDisplay := "Heart rate"

obs := r4.NewObservationBuilder().
    SetId("obs-123").
    SetStatus(r4.ObservationStatusFinal).
    SetCode(r4.CodeableConcept{
        Coding: []r4.Coding{
            {System: &codeSystem, Code: &codeCode, Display: &codeDisplay},
        },
    }).
    SetEffectiveDateTime("2024-01-15T10:30:00Z").
    Build()

data, _ := r4.Marshal(obs)
fmt.Println(string(data))

Siguientes Pasos

Última actualización