Désérialisation : qu’est-ce que c’est, processus de restauration des données

Auteur : IT Sectr Publié le : 2026-03-08 Temps de lecture : 9 min

La désérialisation est le processus de restauration d’un objet à partir d’un flux de données JSON, XML ou Protobuf, essentiel pour toute application mobile fonctionnant avec une API distante. Selon Apple Developer (2026), le traitement incorrect des données entrantes reste l’une des causes fréquentes de plantages sur les appareils. JSONDecoder sur iOS et Gson sur Android sont des outils standard, mais chacun a ses propres caractéristiques et limitations.

Points clés

  • Désérialisation est la restauration d’un objet typé à partir de JSON, XML ou Protobuf pour utilisation dans le code.
  • Codable est le protocole d’Apple pour la désérialisation automatique en Swift avec prise en charge de la génération de code.
  • Moshi est une bibliothèque Android de Square avec des options codegen et reflection pour différents scénarios.
  • Type mismatch est l’erreur la plus courante lorsque les types de champs JSON et les propriétés du modèle ne correspondent pas.
  • kotlinx.serialization est la solution officielle de JetBrains avec génération de code sécurisée par le compilateur.

Qu’est-ce que la désérialisation ?

Désérialisation est le processus de conversion d’un flux d’octets ou d’un texte structuré en un objet de langage de programmation. Dans le développement mobile, ce processus se produit chaque fois qu’une application reçoit une réponse du serveur : une chaîne JSON se transforme en une instance de la classe User, Order ou Product. La stabilité des écrans affichant les données à l’utilisateur dépend directement de la correction de la désérialisation.

Différence avec la sérialisation

La sérialisation et la désérialisation sont des processus mutuellement inverses, rarement symétriques en pratique. La sérialisation convertit un objet en une chaîne pour l’envoyer au serveur, tandis que la désérialisation restaure l’objet à partir de la chaîne reçue. Le serveur peut envoyer un champ qui n’existe pas dans le modèle client, utiliser un format de date différent ou retourner null au lieu d’un nombre. Selon Square Engineering (2025), l’asymétrie des formats provoque 23 % des erreurs de la couche réseau dans les applications Android. Pour réduire le risque, on utilise le versionnage de schéma et la spécification contractuelle stricte via OpenAPI.

Formats de données pour la désérialisation

JSON reste le format le plus populaire pour les API mobiles grâce à sa lisibilité humaine et à sa prise en charge native. Protobuf de Google est utilisé dans les systèmes à haute charge — il est 3 à 6 fois plus compact que JSON et s’analyse plus rapidement, mais nécessite une génération de code à partir de fichiers .proto et n’est pas lisible sans outils. XML est moins courant dans les applications mobiles modernes, mais il est utilisé dans les services SOAP des systèmes d’entreprise et les fichiers de configuration Android. MessagePack est un format binaire similaire à JSON en structure mais plus compact, populaire dans les systèmes temps réel.

Comment fonctionne la désérialisation

Le processus de désérialisation passe par trois étapes. D’abord, la tokenisation divise le texte brut en tokens : clés, chaînes, nombres et délimiteurs. Ensuite, l’analyse syntaxique vérifie la correction de la structure — si les parenthèses sont fermées, si le type de guillemets est correct, si le format est conforme à la RFC 8259. La dernière étape est le mappage sur le modèle objet de l’application, où chaque clé JSON se voit attribuer une propriété de classe en tenant compte de la stratégie de nommage.

Reflection vs Code generation

Deux approches de mappage ont émergé dans le développement mobile. Reflection (Gson, JSONSerialization) analyse la structure de la classe à l’exécution via l’API Java Reflection ou le runtime Objective-C — c’est flexible et ne nécessite pas de configuration supplémentaire, mais c’est plus lent et consomme plus de mémoire. Code generation (Moshi codegen, kotlinx.serialization, Codable) génère du code à la compilation : plus rapide, plus sûr en termes de types et n’expose pas la structure interne via la reflection. JetBrains et Square recommandent la génération de code pour les builds de production — les gains de performance atteignent 2 à 4 fois dans les benchmarks de Google.

swift
struct User: Codable {
    let id: Int
    let name: String
    let email: String
    let createdAt: Date
}

let json = """
{
    "id": 42,
    "name": "Alice",
    "email": "alice@example.com",
    "created_at": "2026-06-01T12:00:00Z"
}
"""
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let user = try decoder.decode(User.self, from: data)

Exemple de désérialisation JSON en modèle User en Swift. La stratégie convertFromSnakeCase convertit automatiquement les clés API en snake_case en propriétés du modèle en camelCase — une pratique standard dans les projets iOS. Le paramètre data sont les octets bruts de la réponse serveur obtenus via URLSession. La gestion des erreurs via try permet d’intercepter un JSON malformé sans planter l’application.

Le rôle des stratégies de décodage

JSONDecoder prend en charge quatre stratégies de clés : useDefaultKeys (correspondance exacte), convertFromSnakeCase (snake_case → camelCase), custom (closure) et convertFromKebabCase (kebab-case → camelCase). Pour les dates, .iso8601, .secondsSince1970, .millisecondsSince1970 et un dateFormatter personnalisé sont disponibles. Choisir la bonne stratégie est la première étape vers une désérialisation robuste, évitant la plupart des erreurs d’inadéquation de formats.

Désérialisation sur iOS

JSONDecoder est le mécanisme standard de désérialisation dans le SDK iOS, fonctionnant avec le protocole Codable. JSONDecoder analyse automatiquement JSON en instances de struct ou class, prenant en charge les objets imbriqués, les tableaux et les primitifs. Pour la logique personnalisée, la méthode init(from: Decoder) est utilisée — elle permet de traiter les formats non standard, les champs manquants dans une ancienne version d’API ou de combiner plusieurs clés JSON en une seule propriété.

swift
struct Order: Decodable {
    let orderId: String
    let amount: Double
    let status: OrderStatus

    enum OrderStatus: String, Decodable {
        case pending, confirmed, shipped, cancelled
    }
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let order = try decoder.decode(Order.self, from: jsonData)

DateDecodingStrategy détermine comment JSONDecoder interprète les chaînes de date. .iso8601 est le plus utilisé — le format standard des API REST. L’enum imbriqué OrderStatus est automatiquement décodé à partir de valeurs de chaîne JSON. Cela évite les nombres magiques et rend le code auto-documenté — le statut de la commande a toujours un ensemble de valeurs strictement défini.

Property Wrappers dans Codable

Depuis Swift 4.2, Codable prend en charge les property wrappers pour la désérialisation personnalisée de propriétés individuelles. @DefaultValue est un wrapper populaire qui définit une valeur par défaut si le champ est absent du JSON. @LosslessString convertit une chaîne en nombre et vice versa. C’est particulièrement utile lorsque le serveur envoie un id sous forme de chaîne "123" mais que le modèle attend un Int. Les property wrappers réduisent le code standard dans init(from:) et rendent les modèles plus propres.

Désérialisation sur Android

Sur Android, le choix de la bibliothèque de désérialisation dépend de la langue et des exigences du projet. Gson de Google est l’option la plus courante, fonctionnant via reflection mais ayant des problèmes de performance sur les hiérarchies complexes. Moshi de Square prend en charge à la fois la reflection et la génération de code, consomme moins de mémoire et traite les réponses volumineuses plus rapidement. kotlinx.serialization de JetBrains est une solution native Kotlin avec intégration au compilateur qui n’utilise pas du tout la reflection.

kotlin
@Serializable
data class User(
    @SerialName("user_id")
    val userId: Int,
    val name: String,
    val email: String,
    @SerialName("created_at")
    val createdAt: String
)

val json = Json { ignoreUnknownKeys = true }
val user = json.decodeFromString<User>(response)

@Serializable est une annotation du compilateur Kotlin qui active la génération de code pour la classe. Le paramètre ignoreUnknownKeys évite les plantages si le serveur envoie un champ absent du modèle. Pour le mappage des clés snake_case, @SerialName est utilisé — l’équivalent de convertFromSnakeCase d’iOS. Selon JetBrains (2026), la bibliothèque prend en charge le multiplateforme : la même classe Serializable fonctionne sur Android, iOS (KMP) et Kotlin côté serveur.

Comparaison de Gson, Moshi et kotlinx.serialization

Le choix entre les bibliothèques se résume à un compromis vitesse-flexibilité. Gson est bon pour les prototypes et les projets Java — il ne nécessite pas d’annotations et fonctionne immédiatement. Moshi occupe une position intermédiaire : codegen via @JsonClass(generateAdapter = true) offre une vitesse proche de kotlinx.serialization, tandis que le mode reflection offre la flexibilité de Gson. kotlinx.serialization est l’option la plus rapide pour les projets Kotlin purs, mais nécessite Kotlin 1.4+ et le plugin Kotlin Serialization dans Gradle.

BibliothèqueMécanismeVitesseKMP
GsonReflectionFaibleNon
MoshiReflection / CodegenMoyenne / ÉlevéeNon
kotlinx.serializationCodegen du compilateurÉlevéeOui

Erreurs typiques et leur prévention

Type mismatch est une situation où JSON contient une valeur d’un type mais le modèle en attend un autre. Le serveur a envoyé la chaîne "42" au lieu d’un nombre, ou le nombre 1 au lieu d’un booléen true. Sur iOS, JSONDecoder lancera DecodingError.typeMismatch par défaut ; sur Android, Gson tentera la conversion, tandis que Moshi et kotlinx.serialization nécessitent des adaptateurs explicites. La solution est d’utiliser des stratégies lenient ou des désérialiseurs personnalisés pour des champs spécifiques.

Champs manquants et nullable

Lorsque le serveur n’inclut pas un champ optionnel, le code plante avec une erreur. Les champs Optional en Swift et les types nullable en Kotlin résolvent le problème : si le champ est null ou absent du JSON, la propriété reçoit nil/null et l’application continue de fonctionner. Pour les champs obligatoires, il convient de vérifier leur présence au niveau du client API avant la désérialisation. Moshi et kotlinx.serialization exigent tous les champs par défaut — le marquage nullable et les valeurs par défaut suppriment cette restriction.

Incompatibilité des versions d’API

Les modifications de la structure JSON sur le serveur sont une source fréquente de plantages en production. La pratique standard est le versionnage de schéma via un champ version dans l’objet racine et le support de 2-3 versions précédentes sur le client. kotlinx.serialization permet de déclarer plusieurs modèles pour différentes versions et de sélectionner le bon en fonction du champ version après l’analyse initiale en JsonElement. La protection supplémentaire inclut ignoreUnknownKeys pour les nouveaux champs et des valeurs par défaut pour les champs susceptibles d’être supprimés.

ErreurSymptômeBibliothèque avec protection
Type mismatchDecodingError / Exceptionkotlinx — coerceInputValues = true
Champ manquantPlantage à l’accèsMoshi — @Transient + default
Format de date incorrectErreur de décodageJSONDecoder — dateDecodingStrategy
Champs supplémentairesIgnorés ou plantagekotlinx — ignoreUnknownKeys = true
Null dans un champ non nullablePlantage à l’exécutionMoshi — lenient avec @Nullable

Journalisation des erreurs de désérialisation est une pratique obligatoire en production. Encapsulez decode dans do/catch, enregistrez le JSON brut et le type de modèle attendu dans Crashlytics ou Sentry. Cela permettra d’identifier rapidement quel champ de quelle API s’est cassé et sur quelle version de l’application. Sans journalisation, une erreur de désérialisation ressemble à un plantage mystérieux sans contexte.

Questions fréquentes

En quoi la désérialisation diffère-t-elle du parsing ?

Le parsing est l’analyse d’un texte structuré en éléments constitutifs sans nécessairement créer un modèle typé. La désérialisation est un cas particulier du parsing dont le résultat est un objet linguistique complet avec des types de propriétés connus. Le parsing peut être par flux, la désérialisation crée toujours un objet complet.

Quelle bibliothèque de désérialisation choisir pour un nouveau projet Android ?

Pour un projet en Kotlin pur, kotlinx.serialization est recommandée — elle est intégrée au compilateur, n’utilise pas la reflection et prend en charge Kotlin Multiplatform. Pour un projet Java existant — Moshi avec code generation. Gson est mieux laissé aux projets legacy où son remplacement nécessiterait un effort important.

Que faire si le serveur envoie du snake_case mais que le modèle utilise du camelCase ?

Sur iOS, utilisez keyDecodingStrategy = .convertFromSnakeCase dans JSONDecoder. Sur Android avec kotlinx.serialization, utilisez @SerialName pour chaque champ. Dans Moshi, appliquez @Json(name="field_name") ou un JsonAdapter.Factory global. Un style cohérent au niveau du projet est une bonne pratique convenue dans le contrat de l’API.

Pourquoi la désérialisation plante-t-elle en production mais pas en développement ?

La raison la plus courante est un null inattendu du serveur sur un champ déclaré comme obligatoire. En développement, le serveur renvoie des données complètes ; en production, il renvoie une réponse réduite. Solution : marquez tous les champs potentiellement absents comme nullable (Kotlin) ou optional (Swift), utilisez ignoreUnknownKeys et des valeurs par défaut.

Qu’est-ce qui est le plus rapide — Reflection ou Code generation en désérialisation ?

Code generation (Moshi codegen, kotlinx.serialization, Codable) est 2 à 4 fois plus rapide que la reflection dans les benchmarks de Google. En plus de la vitesse, la génération de code est plus sûre en termes de types, ne nécessite pas de métadonnées de classe à l’exécution et les erreurs de type sont détectées à la compilation, pas pendant la désérialisation.

Résumé

  • Désérialisation est un processus fondamental du développement mobile qui restaure un objet à partir de JSON, XML ou Protobuf pour utilisation dans le code de l’application.
  • iOS utilise JSONDecoder avec le protocole Codable, offrant une conversion automatique de JSON en modèle avec des stratégies de clés et de dates.
  • Android propose trois outils : Gson (reflection), Moshi (reflection/codegen) et kotlinx.serialization (génération par compilateur via @Serializable).
  • Erreurs courantes — type mismatch, champs manquants, null dans les champs non nullable et incompatibilité des versions d’API — sont évitées par les types nullable, ignoreUnknownKeys et le versionnage.
  • Code generation est plus sûre et plus rapide que la reflection, donc recommandée pour les builds de production des applications mobiles.
  • Stratégie de mappage — keyDecodingStrategy sur iOS et @SerialName sur Android résolvent l’inadéquation des styles de nommage entre le serveur et le client.
  • Il est obligatoire de journaliser les erreurs de désérialisation dans Crashlytics ou Sentry pour un diagnostic rapide des incidents de production.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi