json_serializable con build_runner en Flutter: ejercicio resuelto
json_serializable con build_runner en Flutter: ejercicio resuelto
Escribir fromJson y toJson a mano es repetitivo y propenso a errores. json_serializable genera ese código automáticamente a partir de anotaciones, y es más ligero que Freezed cuando solo necesitas serialización sin inmutabilidad ni union types.
Enunciado
Crea un modelo User con campos obligatorios y opcionales, serializable desde/hacia JSON. Demuestra:
- Campos con nombre diferente en JSON (
@JsonKey). - Campos opcionales con valor por defecto.
- Serialización de listas anidadas.
- Lista de usuarios desde un JSON array.
Dependencias
Cómo ejecutar build_runner
Solución: modelo User
Solución: función de parseo de lista
Uso completo
Archivo generado: user_dto.g.dart
Después del build obtienes algo así (no lo edites):
Errores frecuentes
- Olvidar
part 'user_dto.g.dart': el compilador no encuentra_$UserDtoFromJsony falla. - Cambiar el nombre del campo sin actualizar
@JsonKey: el campo no se deserializa y queda con el valor por defecto silenciosamente. - No añadir
@JsonKey(defaultValue: ...)en campos opcionales: si la API omite el campo,fromJsonlanzaNull check operator used on a null value.
json_serializable vs Freezed
| Necesidad | json_serializable | Freezed |
|---|---|---|
| fromJson / toJson | ✅ | ✅ |
| copyWith generado | ❌ | ✅ |
| == y hashCode generados | ❌ | ✅ |
| Union types | ❌ | ✅ |
| Menos dependencias | ✅ | ❌ |
Usa json_serializable solo si no necesitas inmutabilidad profunda. En proyectos medianos y grandes, Freezed merece la pena.
Aplicación práctica
Cualquier app que consuma una API JSON se beneficia de este flujo: defines el DTO, anotas, ejecutas build_runner y ya tienes serialización robusta y tipada sin código manual.
Siguiente ejercicio recomendado
- Freezed y json_serializable en Flutter: ejercicio resuelto
- Mapper DTO a dominio en Flutter: ejercicio resuelto
- Consumo de API con http en Flutter: ejercicio resuelto
- Todos los ejercicios de Flutter
Práctica guiada y siguiente paso
- Más ejercicios de Flutter
- Ejercicios C para reforzar fundamentos
- Programación en C en 100 ejercicios resueltos
- Ver el libro en Amazon (incluido en Kindle Unlimited)
- Suscribirte a la newsletter
FAQ
¿Genera build_runner código para todas las clases del proyecto a la vez?
Sí. Un solo build_runner build procesa todos los archivos anotados del proyecto. Si solo quieres procesar un archivo, no hay forma nativa de hacerlo selectivamente.
¿Puedo usar explicitToJson: true para clases anidadas?
Sí. Añade @JsonSerializable(explicitToJson: true) si tienes objetos anidados que también tienen toJson; de lo contrario se serializan como Map<String, dynamic> sin llamar a su toJson.
¿Funciona con enums?
Sí. Añade @JsonValue('valor_en_json') a cada valor del enum y @JsonKey(unknownEnumValue: MiEnum.unknown) en el campo para manejar valores inesperados de la API.