Serileştirme, bir nesneyi veya veri yapısını ağ üzerinden iletim veya dosyaya kayıt için uygun sıralı bir biçime dönüştürme işlemidir. Ters işlem olan seri durumdan çıkarma, verileri orijinal durumuna geri yükler. MDN Web Docs'a göre, serileştirme herhangi bir işlemler arası iletişim için gereklidir. Serileştirme, REST API'lerinin, önbelleğe almanın ve uygulama bileşenleri arasında veri alışverişinin temelini oluşturur.
Temel Noktalar
Serileştirme, RAM'de bulunan bir nesneyi ağ üzerinden iletilebilen, bir dosyaya kaydedilebilen veya başka bir işleme aktarılabilen doğrusal bir dizi bayt veya karaktere dönüştürme işlemidir. Serileştirme olmadan ağ iletişimi, durum kalıcılığı ve işlemler arası etkileşim imkansız olurdu.
Serileştirme iki karşıt süreç içerir. İleri yönlü süreç (serileştirme) verileri bir iletim biçimine paketler. Ters süreç (seri durumdan çıkarma) verileri nesneye geri yükler. Seri durumdan çıkarma güvenlik için kritiktir: yanlış girdi verileri uygulamada güvenlik açıklarına yol açabilir.
Mobil uygulama geliştirmede serileştirme her yerde kullanılır: sunucuya istek gönderme ve yanıtları işleme, ekran döndürmede uygulama durumunu kaydetme, diskte veri önbelleğe alma ve Intent (Android) veya Segue (iOS) aracılığıyla ekranlar arasında veri aktarma.
Serileştirme biçimleri, metin ve ikili olarak ikiye ayrılır. Metin biçimleri (JSON, XML) insan tarafından okunabilir ve görüntülemek için araç gerektirmez. İkili biçimler (Protobuf, FlatBuffers, MessagePack) daha kompakt ve hızlıdır, ancak seri durumdan çıkarma olmadan okunamaz. Biçim seçimi, performans ve hata ayıklama kolaylığı arasında bir dengedir.
JSON, XML ve Protobuf'un yanı sıra özelleşmiş biçimler de vardır: Google'dan oyunlar ve AR için FlatBuffers, MessagePack — JSON'a kompakt bir ikili alternatif, Apache'den Kafka'da büyük veri için Avro, YAML — yorum desteği olan bir yapılandırma biçimi.
| Biçim | Tür | Şema | Boyut | Hız |
|---|---|---|---|---|
| JSON | Metin | İsteğe bağlı | Orta | Orta |
| XML | Metin | XSD | Büyük | Düşük |
| Protobuf | İkili | Zorunlu | Küçük | Yüksek |
| FlatBuffers | İkili | Zorunlu | Küçük | Maksimum |
| MessagePack | İkili | Hayır | Küçük | Yüksek |
| Avro | İkili | JSON Schema | Küçük | Yüksek |
Mobil platformlarda serileştirmenin kendine özgü yönleri vardır: sınırlı trafik, daha zayıf işlemciler ve ekran dönüşlerinde durumu koruma ihtiyacı. Android'de Gson, Moshi, Kotlinx Serialization kullanılır. iOS'ta — Codable, JSONSerialization, PropertyListEncoder. Doğru kütüphane seçimi uygulama performansını kritik şekilde etkiler.
Kotlinx Serialization, Kotlin Multiplatform Mobile için JetBrains'in modern bir kütüphanesidir. JSON, Protobuf, CBOR ve özel biçimleri destekler. Kotlin Serialization eklentisi aracılığıyla derleme zamanında kod üretimi gerçekleşir ve yansıma kullanmadan yüksek performans sağlar.
Kotlinx Serialization kütüphanesi, sınıflar için @Serializable notasyonunu ve serileştiriciler oluşturmak için bir derleyici eklentisi kullanır. Bu, yüksek performans ve tür güvenliği sağlar. Varsayılan biçim JSON'dur, ancak ek modüller aracılığıyla diğer biçimler de desteklenir.
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)
// Serileştirme
val jsonString = json.encodeToString(project)
// Seri durumundan çıkarma
val restored = json.decodeFromString<Project>(jsonString)
}
Codable protokolü, Swift'in yerleşik serileştirme mekanizmasıdır. Encodable (serileştirme) ve Decodable (seri durumdan çıkarma) protokollerini birleştirir. JSONEncoder ve JSONDecoder, iç içe yapıları, dizileri, isteğe bağlı değerleri ve CodingKeys aracılığıyla özel anahtarları otomatik olarak işler.
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)
Serileştirme biçimlerinin performansı üç ölçütle değerlendirilir: mesaj boyutu, serileştirme hızı ve seri durumdan çıkarma hızı. Mobil uygulamalar için her üçü de kritiktir: boyut trafiği ve yükleme süresini etkiler, hız arayüz yanıt verebilirliğini ve uygulama başlatma süresini etkiler.
Protobuf ve FlatBuffers, ikili temsil sayesinde en iyi sonuçları gösterir. FlatBuffers, ayrı bir seri durumdan çıkarma adımı gerektirmemesiyle öne çıkar — veriler dönüştürme olmadan doğrudan ikili arabellekten okunur, bu da onu minimum gecikme gereksinimi olan oyunlar ve AR uygulamaları için ideal hale getirir. JSON, daha düşük performansına rağmen, basitliği ve evrenselliği sayesinde REST API'leri için en popüler biçim olmaya devam etmektedir.
| Senaryo | Önerilen Biçim | Neden |
|---|---|---|
| REST API | JSON | Evrensellik, okunabilirlik, destek |
| Mikroservisler | Protobuf | Kompaktlık, hız, gRPC |
| Oyunlar / AR | FlatBuffers | Zero-copy, minimum gecikme |
| Büyük Veri | Avro | Kafka ve Hadoop ile uyumluluk |
| Yapılandırma | YAML | Yorumlar, okunabilirlik |
| Android düzenleri | XML | Platform standardı |
1000 kullanıcı nesnesinden oluşan bir veri kümesi üzerinde yapılan pratik testler gösteriyor: Protobuf 12 KB mesaj oluşturuyor (JSON — 85 KB, XML — 120 KB). Serileştirme süresi: Protobuf — 2 ms, JSON — 8 ms, XML — 25 ms. Bu rakamlar, ikili biçimleri yüksek yüklü sistemler ve sınırlı trafiğe sahip mobil uygulamalar için tercih edilir kılmaktadır.
Örnekler, aynı nesnenin farklı biçimlerde serileştirilmesini gösterir. Bu, boyutu ve okunabilirliği görsel olarak karşılaştırmaya yardımcı olur. Aynı User nesnesi JSON, XML ve Protobuf'ta serileştirilecek — JSON'un XML'den daha kompakt olduğu ve Protobuf'un en kompakt ve okunamaz olduğu açıkça görülecektir.
JSON — minimalist sözdizimi, tırnak içinde anahtarlar, farklı türlerde değerler. 80 karakter kaplar. Okunabilirlik yüksek, görsel yapı net. Geliştirme ve hata ayıklama hızının önemli olduğu API'ler için uygundur.
XML — her öğe açılış ve kapanış etiketleriyle sarılır. 150 karakter kaplar. Okunabilirlik orta, yapı katı. Belge iş akışları ve XSD doğrulaması gerektiren sistemler için uygundur.
Protobuf — ikili, bu veriler için 32 bayt. Okunamaz — görüntülemek için seri durumdan çıkarma gerekir. Minimum boyutuyla yüksek yüklü sistemler ve mobil uygulamalar için idealdir.
{
"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>
En iyi uygulamalar, yaygın hatalardan kaçınmanıza ve projeniz için doğru serileştirme stratejisini seçmenize yardımcı olur. Bu önerilere uymak performansı, güvenliği ve kod bakımını iyileştirir.
Serileştirme güvenliği, özellikle güvenilmeyen kaynaklardan gelen verilerin seri durumdan çıkarılması söz konusu olduğunda kritik derecede önemli bir husustur. Seri durumdan çıkarma saldırıları, web ve mobil uygulamalardaki en tehlikeli güvenlik açıklarından biri olan uzaktan kod yürütmeye (RCE) yol açabilir. En bilinen vakalar Java Serializable ve Python pickle ile ilgilidir.
Protobuf ve JSON, bu tür saldırılara karşı yerleşik korumaya sahiptir, çünkü yalnızca verilerle çalışırlar, rastgele nesnelerle değil. Buna karşılık, Java Serializable, classpath'te bulunan herhangi bir sınıfı geri yükleyebilir ve bu da onu harici kaynaklardan veri almak için tehlikeli hale getirir. Android'de, standart Java Serialization yerine Kotlinx Serialization veya Moshi kullanılması önerilir.
Ek güvenlik önlemleri: girdi verisi boyutuna bir sınır belirleyin, seri durumdan çıkarmadan önce şemayı doğrulayın, HTTP başlıklarındaki Content-Type'a güvenmeyin, izin verilen sınıflar için bir beyaz liste kullanın. Serileştirme kütüphanelerini düzenli olarak güncelleyin, çünkü güvenlik açıkları periyodik olarak keşfedilir ve düzeltilir.
Sıkça sorulan sorular
Serileştirme bir nesneyi bayt dizisine dönüştürürken, marshalling türleri ve yapıyı koruyarak verileri farklı adres alanları arasında aktarır. Marshalling, sürecin bir parçası olarak serileştirmeyi içerir, ancak referans kodlaması ve bellek yönetimini de içerebilir.
Google'ın FlatBuffers'i, sıfır kopyalı seri durumdan çıkarma sayesinde maksimum hız sağlar — veriler dönüşüm olmadan doğrudan ikili arabellekten okunur. Protobuf ikinci sırada, JSON üçüncü sıradadır. XML, yaygın biçimler arasında en yavaş olanıdır.
Kotlinx Serialization, yeni Kotlin projeleri için en iyi seçimdir: derleyici üretimi, Kotlin Multiplatform desteği, null safety. Moshi, Java projeleri için iyi bir seçimdir, Gson'dan daha performanslıdır. Gson, başlamak için en basit kütüphanedir ancak daha yavaştır ve yansıma kullanır.
Döngüel referanslar, serileştirme sırasında sonsuz özyinelemeye yol açar. Çözümler: doğrudan nesne referansları yerine ID referansları kullanın, özelleşmiş serileştirme adaptörleri uygulayın (örn. Jackson'da @JsonIgnore) veya döngüleri ortadan kaldırmak için veri modelini yeniden tasarlayın.
Evet, özellikle güvenilmeyen verilerin seri durumdan çıkarılması. Seri durumdan çıkarma güvenlik açıkları, uzaktan kod yürütmeye yol açabilir. Öneriler: güvenilmeyen kaynaklardan gelen verileri seri durumdan çıkarmayın, seri durumdan çıkarma sırasında bir sınıf beyaz listesi kullanın ve işlemeden önce veri şemasını doğrulayın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun