Moshi হল Square-এর তৈরি একটি আধুনিক JSON লাইব্রেরি, যা Gson-এর সীমাবদ্ধতা বিবেচনায় রেখে বিশেষভাবে Kotlin এবং Android-এর জন্য তৈরি করা হয়েছে। এটি Kotlin-এর null-নিরাপত্তার সাথে সম্পূর্ণ সামঞ্জস্যপূর্ণ, কম্পাইল সময়ে কোড জেনারেট করে এবং রিফ্লেকশন ব্যবহার করে না, যা কর্মক্ষমতা এবং নির্ভরযোগ্যতা উন্নত করে। Square Moshi, 2024 অনুসারে, Moshi পূর্বানুমানযোগ্য সিরিয়ালাইজেশন প্রদান করে এবং যেকোনো ডেটা প্রকারের জন্য কাস্টম অ্যাডাপ্টার সমর্থন করে।
মূল পয়েন্ট
Moshi হল JVM, Android এবং Kotlin Multiplatform-এর জন্য একটি JSON লাইব্রেরি, যা Square (OkHttp এবং Retrofit-এর নির্মাতা) তৈরি করেছে। Gson-এর বিপরীতে, Moshi রিফ্লেকশনের উপর নির্ভর করে না — অ্যাডাপ্টারগুলি @JsonClass(generateAdapter = true) অ্যানোটেশনের মাধ্যমে কম্পাইল সময়ে জেনারেট হয়। এটি Moshi-কে Kotlin-নির্দিষ্ট কাঠামোর সাথে কাজ করার সময় দ্রুততর, নিরাপদ এবং আরও পূর্বানুমানযোগ্য করে তোলে।
Moshi এবং এর পূর্বসূরীদের মধ্যে প্রধান পার্থক্য হল রিফ্লেকশন ত্যাগ করা। রিফ্লেকশন Gson-কে প্রস্তুতি ছাড়াই যেকোনো ক্লাসের সাথে কাজ করতে দেয়, কিন্তু এর মূল্য হল ধীর ইনিশিয়ালাইজেশন, কম্পাইলার দ্বারা অপ্টিমাইজেশনের অসম্ভবতা এবং রানটাইম ত্রুটির ঝুঁকি। Moshi-র কোড জেনারেশনের জন্য স্পষ্ট ক্লাস ঘোষণার প্রয়োজন হয়, কিন্তু বিনিময়ে এটি হাতে-লেখা কোডের গতি এবং কম্পাইল সময়ে সম্পূর্ণ টাইপ নিরাপত্তা প্রদান করে।
// build.gradle-এ Moshi যোগ করুন
dependencies {
implementation "com.squareup.moshi:moshi:1.15.0"
implementation "com.squareup.moshi:moshi-kotlin:1.15.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.15.0"
}
// কোড জেনারেশন সহ সহজ মডেল
@JsonClass(generateAdapter = true)
data class User(
@Json(name = "user_id")
val id: Int,
val name: String,
val email: String,
val avatar: String? = null
)
// ব্যবহার
val moshi = Moshi.Builder()
.build()
val jsonAdapter = moshi.adapter(User::class.java)
Moshi-র সাথে কাজ শুরু করতে, build.gradle-এ ডিপেন্ডেন্সি যোগ করা এবং মডেলগুলিকে অ্যানোটেট করা প্রয়োজন। Moshi.Builder প্রবেশ বিন্দু হিসাবে কাজ করে: এর মাধ্যমে স্ট্যান্ডার্ড প্রকারের জন্য বিল্ট-ইন অ্যাডাপ্টার, কাস্টম অ্যাডাপ্টার যোগ করা হয় এবং লাইব্রেরির আচরণ কনফিগার করা হয়। Moshi Date, Enum, Collection এবং Map-এর জন্য অ্যাডাপ্টার বক্সের বাইরে সমর্থন করে, কিন্তু Kotlin ক্লাসের জন্য moshi-kotlin মডিউল প্রয়োজন। Gson-এর বিপরীতে, Moshi ডিফল্টরূপে Kotlin ক্লাসের জন্য রিফ্লেকশন ব্যবহার করে না — এর জন্য KotlinJsonAdapterFactory সংযুক্ত করা হয়, যা ব্যাকআপ বিকল্প হিসাবে কাজ করে যখন কোড জেনারেশন ব্যবহার করা হয় না বা ক্লাস @JsonClass দিয়ে অ্যানোটেট করা হয় না। এই পদ্ধতি নিশ্চিত করে যে ডেভেলপার প্রতিটি নির্দিষ্ট ক্লাসের জন্য কোড জেনারেশনের কর্মক্ষমতা এবং রিফ্লেকশনের নমনীয়তার মধ্যে স্পষ্টভাবে নির্বাচন করে।
Builder-এর মাধ্যমে Moshi তৈরি করার পর, ডেভেলপার Moshi-র একটি ইনস্ট্যান্স পায় এবং প্রয়োজনীয় ক্লাসের জন্য একটি অ্যাডাপ্টারের অনুরোধ করে। JsonAdapter হল কেন্দ্রীয় অবজেক্ট যা toJson()-এর মাধ্যমে সিরিয়ালাইজেশন এবং fromJson()-এর মাধ্যমে ডিসিরিয়ালাইজেশন সম্পাদন করে। Moshi স্বয়ংক্রিয়ভাবে জেনারেটেড অ্যাডাপ্টার ব্যবহার করে যদি ক্লাসটি @JsonClass(generateAdapter = true) দিয়ে অ্যানোটেট করা হয়, অন্যথায় ব্যাকআপ হিসেবে রিফ্লেক্টিভ KotlinJsonAdapterFactory প্রয়োগ করে। এই পদ্ধতি যেকোনো স্কেল এবং জটিলতার প্রকল্পের জন্য কোড জেনারেশনের গতি এবং রিফ্লেক্টিভ মেকানিজমের নমনীয়তাকে একত্রিত করে। Moshi ছোট অ্যাপ্লিকেশন এবং শত শত ডেটা মডেল সহ বড় এন্টারপ্রাইজ প্রকল্প উভয়ের জন্যই উপযুক্ত।
// KotlinJsonAdapterFactory দিয়ে Moshi কনফিগার করুন
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.add(LocalDateAdapter())
.build()
// অ্যাডাপ্টার ব্যবহার
val adapter = moshi.adapter(User::class.java)
// সিরিয়ালাইজেশন
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)
// ডিসিরিয়ালাইজেশন
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)
// তালিকা নিয়ে কাজ করা
val listAdapter = moshi.adapter(
Types.newParameterizedType(
List::class.java,
User::class.java
)
)
Moshi সিরিয়ালাইজেশন কনফিগার করতে এবং কাস্টম প্রকার সমর্থন করতে অ্যানোটেশন ব্যবহার করে। @Json(name = "...") একটি ফিল্ডের জন্য JSON কী সেট করে। @Transient একটি ফিল্ডকে সিরিয়ালাইজেশন থেকে বাদ দেয়। @JsonClass(generateAdapter = true) কোড জেনারেশন সক্ষম করে। কাস্টম লজিকের জন্য, Moshi @ToJson এবং @FromJson অ্যানোটেশন প্রদান করে, যা একটি পৃথক অ্যাডাপ্টার ক্লাসে স্থাপন করা যেতে পারে।
@Json অ্যানোটেশন Gson-এর @SerializedName প্রতিস্থাপন করে এবং একইভাবে কাজ করে: kotlinName ফিল্ডটি "kotlin_name" JSON কী-এর সাথে সংযুক্ত হয়। যে প্রকারের জন্য Moshi ডিফল্টরূপে সিরিয়ালাইজ করতে পারে না (যেমন LocalDate), ডেভেলপার @ToJson এবং @FromJson পদ্ধতি সহ একটি ক্লাস তৈরি করে। অ্যাডাপ্টারগুলি Moshi.Builder.add()-এর মাধ্যমে নিবন্ধিত হয় এবং বিশ্বব্যাপী বা একটি নির্দিষ্ট প্রকারে প্রয়োগ করা হয়। Moshi সিল ক্লাস এবং @JsonClass-এর মাধ্যমে স্পষ্ট ডিসক্রিমিনেটর সহ পলিমরফিক সিরিয়ালাইজেশন সমর্থন করে, যা ম্যানুয়াল ফিল্ড চেক ছাড়াই JSON-এ টাইপ হায়ারার্কির সাথে কাজ করতে দেয়। ডিসিরিয়ালাইজেশনের সময়, Moshi ডিফল্টরূপে JSON-এ অজানা কী উপেক্ষা করে, যা ক্লায়েন্ট কোড পরিবর্তন না করেই সার্ভার সাইডে নতুন ফিল্ড যোগ করার সময় ব্যাকওয়ার্ড সামঞ্জস্য নিশ্চিত করে। ডিবাগিংয়ের জন্য, failOnUnknown-এর মাধ্যমে কঠোর মোড সক্রিয় করা যেতে পারে, যা অজানা কী পাওয়া গেলে ব্যতিক্রম ছুঁড়ে দেয়।
// LocalDate-এর জন্য কাস্টম অ্যাডাপ্টার
class LocalDateAdapter {
@ToJson
fun toJson(date: LocalDate): String {
return date.format(DateTimeFormatter.ISO_LOCAL_DATE)
}
@FromJson
fun fromJson(dateString: String): LocalDate {
return LocalDate.parse(dateString)
}
}
// Moshi অ্যানোটেশন সহ মডেল
@JsonClass(generateAdapter = true)
data class Event(
@Json(name = "event_id")
val id: Int,
@Json(name = "event_date")
val date: LocalDate,
@Transient
val localCache: String? = null
)
// অ্যাডাপ্টার নিবন্ধন করুন
val moshi = Moshi.Builder()
.add(LocalDateAdapter())
.add(KotlinJsonAdapterFactory())
.build()
Moshi এবং Gson-এর তুলনা Android প্রকল্পের জন্য JSON লাইব্রেরি নির্বাচন করার সময় একটি সাধারণ প্রশ্ন। Moshi কোড জেনারেশন, null নিরাপত্তা এবং গতির কারণে আধুনিক Kotlin ডেভেলপমেন্টে জয়ী হয়। Gson Java প্রকল্প, লিগ্যাসি কোড এবং সেই পরিস্থিতিতে প্রাসঙ্গিক থাকে যেখানে ন্যূনতম কনফিগারেশন গুরুত্বপূর্ণ। পার্থক্য বড় ডেটা ভলিউম এবং জটিল মডেলের সাথে স্পষ্ট হয়ে ওঠে।
কর্মক্ষমতা পরীক্ষা দেখায় যে কোড জেনারেশন সহ Moshi সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশন অপারেশনে Gson-এর থেকে 2–5 গুণ দ্রুততর। Moshi-র মূল সুবিধা হল Kotlin null নিরাপত্তার সঠিক হ্যান্ডলিং: যদি JSON-এ একটি ফিল্ড অনুপস্থিত থাকে এবং মডেলটি এটি ডিফল্ট মান ছাড়া non-null হিসাবে ঘোষণা করে, Moshi ডিসিরিয়ালাইজেশনের সময় একটি ব্যতিক্রম ছুঁড়ে দেয়, লুকানো ত্রুটিগুলি প্রতিরোধ করে।
| বৈশিষ্ট্য | Gson | Moshi |
|---|---|---|
| পদ্ধতি | রিফ্লেকশন | কোড জেনারেশন / রিফ্লেকশন |
| Null নিরাপত্তা | বিবেচনা করে না | সম্পূর্ণ Kotlin সমর্থন |
| গতি | মধ্যম | উচ্চ |
| ডিফল্ট মান | সমর্থন করে না | সমর্থন করে |
| Kotlin Multiplatform | না | হ্যাঁ |
| লাইব্রেরির আকার | ~240 Kb | ~150 Kb |
Moshi এবং Gson-এর মধ্যে নির্বাচন প্রকল্পের প্রসঙ্গের উপর নির্ভর করে। Kotlin-এ নতুন প্রকল্প টাইপ নিরাপত্তা এবং কর্মক্ষমতার কারণে Moshi থেকে সুবিধা পায়। Gson Java কোড, ডায়নামিক JSON কাঠামো সমর্থনের জন্য বা যখন কনফিগারেশনের সরলতা গতির চেয়ে বেশি গুরুত্বপূর্ণ তখন একটি যুক্তিসঙ্গত পছন্দ থাকে। Kotlin Multiplatform-এর জন্য, Moshi হল দুটি বিকল্পের মধ্যে একমাত্র যা এই প্ল্যাটফর্মটি সমর্থন করে।
Gson থেকে Moshi-তে মাইগ্রেট করার সময়, প্রধান পরিবর্তনগুলি অ্যানোটেশন এবং অ্যাডাপ্টার সম্পর্কিত। Gson-এর @SerializedName প্রতিস্থাপিত হয় @Json(name = "...") দিয়ে, এবং কাস্টম JsonSerializer/JsonDeserializer @ToJson/@FromJson জোড়া দিয়ে প্রতিস্থাপিত হয়। ডিফল্ট মান এবং nullable ফিল্ড সহ মডেলের জন্য, Moshi আরও পূর্বানুমানযোগ্য আচরণ করে: যদি JSON-এ ডিফল্ট ছাড়া একটি non-null ফিল্ড অনুপস্থিত থাকে, Moshi JsonDataException ছুঁড়ে দেয়, লুকানো NPE প্রতিরোধ করে। MoshiConverterFactory-এর মাধ্যমে Retrofit-এর সাথে ইন্টিগ্রেশন একটি ডিপেন্ডেন্সি দিয়ে যোগ করা হয় এবং নেটওয়ার্ক লেয়ারের আর্কিটেকচার পরিবর্তনের প্রয়োজন হয় না। ProGuard বা R8-এর মাধ্যমে অবফাসকেশনের জন্য, @JsonClass-অ্যানোটেটেড ক্লাস এবং জেনারেটেড অ্যাডাপ্টার সংরক্ষণের নিয়ম যোগ করা প্রয়োজন, অন্যথায় রিলিজ বিল্ডে সিরিয়ালাইজেশন ভেঙে যাবে। সামগ্রিকভাবে, Gson থেকে Moshi-তে মাইগ্রেশন নতুন Kotlin প্রকল্পে যুক্তিযুক্ত যেখানে কর্মক্ষমতা এবং টাইপ নিরাপত্তা গুরুত্বপূর্ণ।
// সিরিয়ালাইজেশন তুলনা: Gson বনাম Moshi
data class Sample(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
// Gson: রিফ্লেকশনের মাধ্যমে কাজ করে
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
Sample::class.java)
// count = 0 (ডিফল্ট), কিন্তু null নিরাপত্তা পরীক্ষা করা হয় না
// Moshi: অ্যাডাপ্টার প্রয়োজন, null নিরাপত্তা স্পষ্ট
@JsonClass(generateAdapter = true)
data class SampleMoshi(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
সচরাচর জিজ্ঞাসিত প্রশ্ন
Moshi হল Square-এর Kotlin এবং Android-এর জন্য একটি JSON লাইব্রেরি যা রিফ্লেকশনের পরিবর্তে কোড জেনারেশন ব্যবহার করে। এটি উচ্চ কর্মক্ষমতা, Kotlin null নিরাপত্তার সঠিক হ্যান্ডলিং এবং Kotlin Multiplatform-এর সাথে সামঞ্জস্য প্রদান করে।
Moshi গতি (কোড জেনারেশনের কারণে 2–5 গুণ দ্রুততর), নিরাপত্তা (Kotlin null অ্যানোটেশন বিবেচনা করে) এবং আকার (~90 Kb ছোট) এ Gson-কে ছাড়িয়ে যায়। Moshi Kotlin Multiplatform এবং data class-এ ডিফল্ট মানও সমর্থন করে।
@JsonClass(generateAdapter = true) Moshi-কে নির্দেশ দেয় যে প্রদত্ত ক্লাসের জন্য কম্পাইল সময়ে একটি অ্যাডাপ্টার জেনারেট করতে। জেনারেটেড অ্যাডাপ্টার সরাসরি সিরিয়ালাইজেশন সম্পাদন করে, রিফ্লেকশন ছাড়াই, যা সর্বোচ্চ কর্মক্ষমতা প্রদান করে।
@ToJson (সিরিয়ালাইজেশন) এবং @FromJson (ডিসিরিয়ালাইজেশন) দিয়ে অ্যানোটেটেড পদ্ধতি সহ একটি ক্লাস তৈরি করুন। Moshi.Builder.add()-এর মাধ্যমে ইনস্ট্যান্স নিবন্ধন করুন। Moshi স্বয়ংক্রিয়ভাবে সংশ্লিষ্ট প্রকারের সাথে কাজ করার সময় অ্যাডাপ্টার খুঁজে পাবে এবং প্রয়োগ করবে।
হ্যাঁ, Moshi সংস্করণ 1.13.0 থেকে Kotlin Multiplatform সমর্থন করে। এটি KMP প্রকল্পের জন্য একমাত্র জনপ্রিয় JSON সমাধান করে তোলে, যা সমস্ত লক্ষ্য প্ল্যাটফর্মে সাধারণ সিরিয়ালাইজেশন কোড ব্যবহার করার অনুমতি দেয়।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন