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
- Aprende sobre las Versiones FHIR y cómo difieren los tres paquetes.
- Explora los patrones de Construcción de Recursos en profundidad.