Серіалізація — це процес перетворення об’єкта або структури даних у послідовний формат, придатний для передачі мережею або збереження у файл. Зворотний процес, десеріалізація, відновлює дані до початкового стану. Згідно з MDN Web Docs, серіалізація необхідна для будь-якої міжпроцесної взаємодії. Серіалізація лежить в основі REST API, кешування та обміну даними між компонентами додатка.
Головне
Серіалізація — це процес перетворення об’єкта, що знаходиться в оперативній пам’яті, в лінійну послідовність байтів або символів, яку можна передати мережею, зберегти у файлі або передати іншому процесу. Без серіалізації неможлива мережева комунікація, збереження стану та міжпроцесна взаємодія.
Серіалізація включає два протилежні процеси. Прямий процес (серіалізація) пакує дані у формат для передачі. Зворотний процес (десеріалізація) відновлює дані обернення в об’єкт. Десеріалізація критично важлива для безпеки: некоректні вхідні дані можуть призвести до вразливостей в додатку.
У розробці мобільних додатків серіалізація використовується повсюди: відправлення запитів на сервер та обробка відповідей, збереження стану додатка при повороті екрану, кешування даних на диску та передача даних між екранами через Intent (Android) або Segue (iOS).
Формати серіалізації поділяються на текстові та бінарні. Текстові формати (JSON, XML) читаються людьми та не вимагають інструментів для перегляду. Бінарні формати (Protobuf, FlatBuffers, MessagePack) компактніші та швидші, але нечитанні без десеріалізації. Вибір формату — компроміс між продуктивністю та зручністю налагодження.
Крім JSON, XML та Protobuf, існують спеціалізовані формати: FlatBuffers від Google для ігор та AR, MessagePack — компактна бінарна альтернатива JSON, Avro від Apache для великих даних у Kafka, YAML — конфігураційний формат з підтримкою коментарів.
| Формат | Тип | Схема | Розмір | Швидкість |
|---|---|---|---|---|
| JSON | Текстовий | Опціонально | Середній | Середня |
| XML | Текстовий | XSD | Великий | Низька |
| Protobuf | Бінарний | Обов’язково | Малий | Висока |
| FlatBuffers | Бінарний | Обов’язково | Малий | Максимальна |
| MessagePack | Бінарний | Ні | Малий | Висока |
| Avro | Бінарний | JSON Schema | Малий | Висока |
Серіалізація на мобільних платформах має свою специфіку: обмежений трафік, слабші процесори та необхідність зберігати стан при поворотах екрану. На Android використовуються Gson, Moshi, Kotlinx Serialization. На iOS — Codable, JSONSerialization, PropertyListEncoder. Правильний вибір бібліотеки критично впливає на продуктивність додатка.
Kotlinx Serialization — сучасна бібліотека від JetBrains для Kotlin Multiplatform Mobile. Вона підтримує JSON, Protobuf, CBOR та користувацькі формати. Генерація коду відбувається на етапі компіляції через плагін Kotlin Serialization, що забезпечує високу продуктивність без використання рефлексії.
Бібліотека Kotlinx Serialization використовує анотацію @Serializable для класів та плагін компілятора для генерації серіалізаторів. Це забезпечує високу продуктивність та типову безпеку. Типовий формат — JSON, але інші формати підтримуються через додаткові модулі.
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
@Serializable
data class Project(
val id: Int,
val name: String,
val platforms: List<String>,
val active: Boolean
)
val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
encodeDefaults = true
}
fun main() {
val project = Project(1, "MobileApp",
listOf("Android", "iOS"), true)
// Сериализация
val jsonString = json.encodeToString(project)
// Десериализация
val restored = json.decodeFromString<Project>(jsonString)
}
Протокол Codable — це вбудований механізм серіалізації в Swift. Він об’єднує протоколи Encodable (серіалізація) та Decodable (десеріалізація). JSONEncoder та JSONDecoder автоматично обробляють вкладені структури, масиви, опціональні значення та користувацькі ключі через CodingKeys.
import Foundation
struct AppConfig: Codable {
let appName: String
let version: String
let features: [String]
let isProduction: Bool
}
let config = AppConfig(
appName: "MyApp",
version: "2.1.0",
features: ["push", "analytics", "offline"],
isProduction: true
)
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
guard let data = try? encoder.encode(config) else { return }
let jsonString = String(data: data, encoding: .utf8)
Продуктивність форматів серіалізації оцінюється за трьома показниками: розмір повідомлення, швидкість серіалізації та швидкість десеріалізації. Для мобільних додатків усі три критичні: розмір впливає на трафік та час завантаження, швидкість впливає на чутливість інтерфейсу та час запуску додатка.
Protobuf та FlatBuffers показують найкращі результати завдяки бінарному поданню. FlatBuffers виділяється тим, що не потребує окремого кроку десеріалізації — дані читаються безпосередньо з бінарного буферу, що робить його ідеальним для ігор та AR-додатків з вимогами мінімальної затримки. JSON залишається найпопулярнішим форматом для REST API, незважаючи на гіршу продуктивність, завдяки своїй простоті та універсальності.
| Сценарій | Рекомендований формат | Причина |
|---|---|---|
| REST API | JSON | Універсальність, читанність, підтримка |
| Мікросервіси | Protobuf | Компактність, швидкість, gRPC |
| Ігри / AR | FlatBuffers | Zero-copy, мінімальна затримка |
| Великі дані | Avro | Сумісність з Kafka та Hadoop |
| Конфігурація | YAML | Коментарі, читанність |
| Android макети | XML | Платформений стандарт |
Практичні тести на наборі даних з 1000 об’єктів користувачів показують: Protobuf створює повідомлення розміром 12 КБ (JSON — 85 КБ, XML — 120 КБ). Час серіалізації: Protobuf — 2 мс, JSON — 8 мс, XML — 25 мс. Ці цифри роблять бінарні формати бажаними для високонавантажених систем та мобільних додатків з обмеженим трафіком.
Приклади демонструють серіалізацію одного й того ж об’єкта в різних форматах. Це допомагає наочно порівняти розмір та читанність. Однойменний об’єкт User буде серіалізовано в JSON, XML та Protobuf — наочно видно, що JSON компактніший за XML, а Protobuf найкомпактніший і нечитанний.
JSON — мінімалістичний синтаксис, ключі в лапках, значення різних типів. Займає 80 символів. Читанність висока, візуальна структура чітка. Підходить для API, де важлива швидкість розробки та налагодження.
XML — кожен елемент обгорнуто в відкриваючий та закриваючий теги. Займає 150 символів. Читанність середня, структура сувора. Підходить для документообігу та систем, що вимагають валідації XSD.
Protobuf — бінарний, 32 байти для цих даних. Нечитанний — потребує десеріалізації для перегляду. Мінімальний розмір робить його ідеальним для високонавантажених систем та мобільних додатків.
{
"id": 42,
"name": "IT Sectr",
"email": "team@itsectr.com",
"role": "admin",
"active": true
}
<user>
<id>42</id>
<name>IT Sectr</name>
<email>team@itsectr.com</email>
<role>admin</role>
<active>true</active>
</user>
Найкращі практики допомагають уникнути типових помилок та вибрати правильну стратегію серіалізації для проєкту. Дотримання цих рекомендацій поліпшує продуктивність, безпеку та підтримку коду.
Безпека серіалізації — критично важливий аспект, особливо при десеріалізації даних з неперевірених джерел. Атаки на десеріалізацію можуть призвести до віддаленого виконання коду (RCE), що є однією з найнебезпечніших вразливостей у веб-та мобільних додатках. Найвідоміші випадки пов’язані з Java Serializable та Python pickle.
Protobuf та JSON мають вбудований захист від таких атак, оскільки працюють лише з даними, а не з довільними об’єктами. Java Serializable, навпаки, може відновлювати будь-який клас, доступний у classpath, що робить його небезпечним для прийому даних з зовнішніх джерел. На Android рекомендується використовувати Kotlinx Serialization або Moshi замість стандартної Java Serialization.
Додаткові заходи безпеки: встановлювайте ліміт на розмір вхідних даних, валідуйте схему перед десеріалізацією, не довіряйте Content-Type з HTTP-заголовків, використовуйте білий список для дозволених класів. Регулярно оновлювайте бібліотеки серіалізації, оскільки вразливості періодично виявляються та виправляються.
Часті запитання
Серіалізація перетворює об’єкт в послідовність байтів, тоді як маршалінг передає дані між різними адресними просторами зі збереженням типів та структури. Маршалінг включає серіалізацію як частину процесу, але також може включати кодування посилань та управління пам’яттю.
FlatBuffers від Google забезпечує максимальну швидкість завдяки zero-copy десеріалізації — дані читаються безпосередньо з бінарного буферу без перетворення. Protobuf на другому місці, JSON — на третьому. XML — найповільніший формат серед поширених.
Kotlinx Serialization — найкращий вибір для нових проєктів на Kotlin: компіляторна генерація, підтримка Kotlin Multiplatform, null safety. Moshi — хороший вибір для проєктів на Java, продуктивніший за Gson. Gson — найпростіша бібліотека для початку, але повільніша та використовує рефлексію.
Циклічні посилання призводять до нескінченної рекурсії під час серіалізації. Рішення: використовуйте ID-посилання замість прямих посилань на об’єкти, застосовувайте спеціалізовані адаптери серіалізації (наприклад, @JsonIgnore в Jackson), або перепроектуйте модель даних для усунення циклів.
Так, особливо десеріалізація неперевірених даних. Вразливості десеріалізації можуть призвести до віддаленого виконання коду. Рекомендації: не десеріалізуйте дані з неперевірених джерел, використовуйте білий список класів під час десеріалізації та валідуйте схему даних перед обробкою.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.