Deserialice JSON en una interface con múltiples implementaciones.
Estoy construyendo un sistema de Event Sourcing con muchos eventos.
Necesito deserializar un objeto JSON en uno de los posibles tipos de evento.
Sé que puedo hacer algo como:
type TypedJson struct {
Type string
Data json.RawMessage
}
func SerializeJson(event IEvent) []byte {
data, _:= json.Marshal(event)
dataType := reflect.TypeOf(event).String()
typeName := dataType[strings.LastIndex(dataType, ".")+1:]
typedThing := TypedJson{typeName, data}
finalJson, _ := json.Marshal(typedThing)
return finalJson
}
func Deserialize(jsonData []byte) IEvent {
var event TypedJson
json.Unmarshal(jsonData, &event)
switch event.Type {
case "UserCreated":
var e UserCreated
json.Unmarshal(event.Data, &e)
return e
case "EmailChanged":
var e EmailChanged
json.Unmarshal(event.Data, &e)
return e
case ...
}
}
Pero parece incómodo cuando hay muchos eventos que considerar.
¿Existe un enfoque mejor?
davy.ai
Una posible manera de simplificar el proceso de deserialización de un objeto json en uno de varios tipos de eventos posibles es utilizar un mapa de nombres de tipo de evento a los tipos de eventos correspondientes, en lugar de usar una sentencia switch con muchos casos. Esto permite agregar fácilmente nuevos tipos de eventos sin tener que modificar el código de deserialización cada vez. Aquí hay un ejemplo:
En este ejemplo, definimos un mapa llamado
eventTypes
que mapea los nombres de cadena de los tipos de eventos a sus tipos de reflexión correspondientes. Luego, en la funciónDeserialize
, usamos este mapa para buscar el tipo de reflexión del evento en función del nombre de tipo en el objeto json. Creamos una nueva instancia del evento utilizando reflexión, lo deserializamos en los datos json y lo devolvemos si es exitoso. Si el tipo no se encuentra en el mapa, devolvemos un error.Este enfoque simplifica el código de deserialización y permite una fácil adición de nuevos tipos de eventos en el futuro.