URI ডিপ লিঙ্ক ম্যাচ করা

প্যাটার্নের সাথে হায়ারার্কিক্যাল URI ম্যাচ করা এবং আর্গুমেন্ট এক্সট্র্যাক্ট করার জন্য, UriDeepLinkMatcher ব্যবহার করুন। এটি আপনার কী ক্লাসে মিলে যাওয়া আর্গুমেন্ট ডিসিরিয়ালাইজ করতে kotlinx.serialization-এর উপর নির্ভর করে।

UriDeepLinkMatcher তৈরি করতে, একটি প্যাটার্ন DeepLinkUri এবং সংশ্লিষ্ট কী-এর জন্য সিরিয়ালাইজার প্রদান করুন:

নন-হায়ারার্কিক্যাল URI বা কাস্টম স্কিমের (যেমন tel:) জন্য, কাস্টম ডিপ লিঙ্ক ম্যাচ করার টুল তৈরি করুন দেখুন।

যেসব ম্যাচিং প্যাটার্নে কাজ করে

UriDeepLinkMatcher পাঁচটি কম্পোনেন্টের ভিত্তিতে URI ম্যাচ করে: স্কিম, কর্তৃপক্ষ, পাথ, কোয়েরি ও ফ্র্যাগমেন্ট। নিম্নলিখিত বিভাগগুলি প্রতিটি উপাদানের জন্য সমর্থিত প্যাটার্ন সিনট্যাক্স, আর্গুমেন্ট প্লেসহোল্ডার এবং ম্যাচিং নিয়মগুলি বর্ণনা করে।

স্কিম ম্যাচিং

URI প্যাটার্নে কোনও স্কিম না থাকলে, http এবং https দুটিই ম্যাচ করা হয়। নির্দিষ্ট স্কিমের সাথে ম্যাচ করতে, প্যাটার্নে এটি অন্তর্ভুক্ত করুন। ব্যতিক্রম হিসেবে, প্যাটার্নে http স্কিম http এবং https অনুরোধ URI-এর সাথে মেলে, যেখানে প্যাটার্নে https শুধুমাত্র https অনুরোধের সাথে মেলে।

প্যাটার্ন URI URI-এর জন্য অনুরোধ করুন মিল
www.example.com https://www.example.com ✅
www.example.com http://www.example.com ✅
http://www.example.com http://www.example.com ✅
http://www.example.com https://www.example.com ✅
https://www.example.com http://www.example.com ❌
myapp://www.example.com myapp://www.example.com ✅

কর্তৃত্ব ম্যাচিং

UriDeepLinkMatcher URI অথরিটি (হোস্ট এবং ঐচ্ছিক পোর্ট)-এর উপর কেস-ইনসেনসিটিভ সম্পূর্ণ ম্যাচ পারফর্ম করে। অথরিটিতে প্লেসহোল্ডার বা ওয়াইল্ডকার্ড কাজ করে না এবং কোনও আর্গুমেন্ট এক্সট্র্যাক্ট করা হয় না:

প্যাটার্ন URI URI-এর জন্য অনুরোধ করুন মিল
example.com https://example.com ✅
example.com https://EXAMPLE.COM ✅
example.com https://sub.example.com ❌
example.com https://www.example.com ❌
example.com https://example.com:8080 ❌
example.com:8080 https://example.com:8080 ✅
example.com:8080 https://example.com ❌

পাথ ম্যাচিং

নিম্নলিখিত পাথ প্যাটার্ন কাজ করে:

প্যাটার্ন URI URI-এর জন্য অনুরোধ করুন মিল এক্সট্র্যাক্ট করা আর্গুমেন্ট
www.example.com/users https://www.example.com/users ✅ কোনওটিই নয়
www.example.com/users/{id} https://www.example.com/users/123 ✅ id: "123"
www.example.com/users/{first}-{last} https://www.example.com/users/john-doe ✅ first: "john", last: "doe"
www.example.com/users/{id}/profile https://www.example.com/users//profile ✅ id: "" (খালি স্ট্রিং)
www.example.com/users/user_{id} https://www.example.com/users/user_123 ✅ id: "123"
www.example.com/users/{userId}/posts/{postId} https://www.example.com/users/123/posts/456 ✅ userId: "123", postId: "456"
www.example.com/users/.* https://www.example.com/users/john-doe ✅ কোনওটিই নয়
www.example.com/users https://www.example.com/users/ ❌ (ট্রেলিং স্ল্যাশ অতিরিক্ত সেগমেন্ট তৈরি করে) N/A

কোয়েরি ম্যাচিং

অনুরোধ URI-তে কোয়েরি প্যারামিটারের ক্রম প্যাটার্ন URI-এর ক্রমের সাথে মিলতে হবে না। এছাড়াও, অনুরোধের URI-তে উপস্থিত প্যারামিটারগুলি কিন্তু প্যাটার্ন URI-তে উপস্থিত নয় এমন প্যারামিটারগুলি উপেক্ষা করা হয়।

নিম্নলিখিত কোয়েরি প্যারামিটার প্যাটার্ন কাজ করে:

প্যাটার্ন URI URI-এর জন্য অনুরোধ করুন এক্সট্র্যাক্ট করা আর্গুমেন্ট
www.example.com/users?name={name} https://www.example.com/users?name=john name: "john"
www.example.com/users?name={name} https://www.example.com/users?name= name: "" (খালি স্ট্রিং)
www.example.com/users?{rawQuery} https://www.example.com/users?anything&else rawQuery: ["anything", "else"]
www.example.com/users?type=user_{id} https://www.example.com/users?type=user_123 id: "123"
www.example.com/users?name={first}_{last} https://www.example.com/users?name=john_doe first: "john", last: "doe"
www.example.com/users?list={list} https://www.example.com/users?list=10&list=20 list: ["10", "20"]
www.example.com/users?name={name}&{other} https://www.example.com/users?name=john&tab=info name: "john", other: ["tab=info"]
www.example.com/users?type=user_.* https://www.example.com/users?type=user_admin type: "admin"

ফ্র্যাগমেন্ট ম্যাচিং

নিম্নলিখিত ফ্র্যাগমেন্ট প্যাটার্নের ধরন কাজ করে:

প্যাটার্ন URI URI-এর জন্য অনুরোধ করুন এক্সট্র্যাক্ট করা আর্গুমেন্ট
www.example.com/#section1 https://www.example.com/#section1 কোনওটিই নয়
www.example.com/#section_{id} https://www.example.com/#section_123 id: "123"
www.example.com/#section_.* https://www.example.com/#section_123 কোনওটিই নয়

যেসব ডেটার ধরন কাজ করে

UriDeepLinkMatcher-এর মাধ্যমে URI আর্গুমেন্টকে প্রিমিটিভ টাইপ, enum, কালেকশন ও কাস্টম অবজেক্টে ডিসিরিয়ালাইজ করা যায়। সিরিয়ালাইজেশনকে দুটি বিভাগে ভাগ করা হয়:

  • স্ট্যান্ডার্ড সিরিয়ালাইজেশন: kotlinx.serialization ব্যবহার করে এতে ডিসিরিয়ালাইজ করে:
    • প্রিমিটিভ (Boolean, Int, Long, Float, Double, Char, Byte, Short) এবং String
    • Enums
    • Set, List বা Arrayটি প্রিমিটিভ, স্ট্রিং বা enum
    • নেস্টেড @Serializable ক্লাস (যার প্রপার্টিগুলি আলাদা URI প্লেসহোল্ডারে ফ্ল্যাটেন করা হয়েছে)
  • DeepLinkSerializer-এর সাথে কাস্টম সিরিয়ালাইজেশন: একটি একক String এবং কাস্টম অবজেক্ট, এক্সটার্নাল ধরন (যেমন java.time.LocalDate) অথবা কাস্টম-ডিলিমিটেড সংগ্রহের মধ্যে কনভার্ট করে।

স্ট্যান্ডার্ড সিরিয়ালাইজেশন

UriDeepLinkMatcher কাস্টম সিরিয়ালাইজার ইমপ্লিমেন্টেশন ছাড়াই স্ট্যান্ডার্ড ধরন ও ফ্ল্যাটেন করা স্ট্রাকচারের জন্য সরাসরি কাজ করে।

প্রিমিটিভ ও স্ট্রিং

UriDeepLinkMatcher অটোমেটিক প্রিমিটিভ টাইপ (Boolean, Int, Long, Float, Double, Char, Byte, Short) এবং String ডিকোড করে:

Enums

Enum এলিমেন্টের নামের সাথে Enum ভ্যালু ম্যাচ করার সময় ছোট ও বড় হাতের অক্ষরের মধ্যে পার্থক্য করা হয়:

বারবার করা কোয়েরির কালেকশন

রিপিট করা কী (যেমন ?id=10&id=20) সহ কোয়েরি প্যারামিটার অটোমেটিক List<T>, Set<T> বা Array<T>-এ ডিসিরিয়ালাইজ করে যেখানে T হল প্রিমিটিভ টাইপ, String বা enum:

নেস্ট করা @Serializable ক্লাস

যখন কোনও NavKey-এ এমন একটি প্রপার্টি থাকে যার ধরন হল অন্য একটি @Serializable ক্লাস, UriDeepLinkMatcher এর প্রপার্টিগুলিকে ফ্ল্যাট করে যাতে নেস্টেড ক্লাসের প্রতিটি প্রপার্টি সরাসরি একই নামের একটি স্বতন্ত্র URI প্যারামিটারে ম্যাপ করে:

কাস্টম অবজেক্ট (যেমন Filter(key = "brand", value = "pixel")), এক্সটার্নাল টাইপ (যেমন java.time.LocalDate) বা কাস্টম ডিলিমিটেড স্ট্রিং (যেমন কমা-সেপারেটেড ভ্যালু) ডিসিরিয়ালাইজ করতে, DeepLinkSerializer<T> এক্সটেন্ড করুন।

DeepLinkSerializer<T> হল একটি অ্যাবস্ট্রাক্ট KSerializer<T> যা String এবং T-এর মধ্যে কনভার্ট করে:

abstract class DeepLinkSerializer<T : Any> : KSerializer<T> {
    abstract val serialName: String
    abstract fun deserialize(value: String): T
    abstract fun serialize(value: T): String
}

যেমন, নিম্নলিখিত স্নিপেটে ব্যবহার করা Filter এবং FilterSerializer-এর সংজ্ঞা বিবেচনা করুন:

একটি কাস্টম অবজেক্ট

একটি URI প্যারামিটার স্ট্রিং (যেমন ?filter=brand:google) থেকে কোনও অবজেক্ট ডিকোড করতে, @Serializable(with = ...) দিয়ে প্রপার্টি অ্যানোটেট করুন:

রিপিট হওয়া কোয়েরি প্যারামিটারে কাস্টম অবজেক্ট

কাস্টম অবজেক্টের (List<T>, Set<T> বা Array<T>) সংগ্রহে বারবার ব্যবহৃত কোয়েরি প্যারামিটার ডিসিরিয়ালাইজ করতে, এলিমেন্টের ধরন T-এর জন্য DeepLinkSerializer<T> প্রয়োগ করুন এবং @Serializable(with = ...)-এর সাথে প্রপার্টির ধরন সংক্রান্ত আর্গুমেন্ট অ্যানোটেট করুন:

সিঙ্গেল প্যারামিটারে ডিলিমিটেড কালেকশন

কমা দ্বারা আলাদা করা বা কাস্টম-ডিলিমিটেড ভ্যালু (যেমন ?ids=1,2,3) একটি কালেকশনে পার্স করতে, সম্পূর্ণ কালেকশন টাইপের জন্য DeepLinkSerializer প্রয়োগ করুন এবং @Serializable(with = ...)-এর মাধ্যমে প্রপার্টি অ্যানোটেট করুন:

আর্গুমেন্ট যাচাইকরণ ও ম্যাচিং ফলাফল

UriDeepLinkMatcher অমিল (null রিটার্ন করে যাতে অন্যান্য ম্যাচ করার চেষ্টা করা যায়) এবং অসমর্থিত কনফিগারেশন (ব্যতিক্রম দেখায়)-এর মধ্যে পার্থক্য করে।

অমিল

ইনকামিং অনুরোধের URI প্যাটার্ন বা ধরনের প্রয়োজনীয়তা পূরণ না করলে অমিল হয়:

  • প্রয়োজনীয় প্যারামিটার নেই: ডিফল্ট ভ্যালু ছাড়া নন-নালেবেল কী প্রপার্টি যার সংশ্লিষ্ট URI প্যারামিটার অনুরোধের URI-তে নেই।
  • টাইপ পার্সিং সংক্রান্ত সমস্যা: এক্সট্র্যাক্ট করা আর্গুমেন্ট ভ্যালু যা প্রত্যাশিত প্রপার্টি টাইপে পার্স করা যায় না (যেমন, Int প্রপার্টির জন্য "abc")।

অমিল হলে, UriDeepLinkMatcher.match null রিটার্ন করে, যা পরবর্তী ম্যাচিংয়ের মূল্যায়ন করার অনুমতি দেয়।

ডিফল্ট ভ্যালু, নেস্টেড অবজেক্ট ও enum সহ কনফিগার করা একটি কী ক্লাস ও ম্যাচারের কথা বিবেচনা করুন:

নিম্নলিখিত সারণীতে বিভিন্ন অনুরোধ URI-এর জন্য ম্যাচিং ফলাফল দেখানো হয়েছে:

URI-এর জন্য অনুরোধ করুন ডিকোডিং সংক্রান্ত ফলাফল ম্যাচের ফলাফল
https://www.example.com/map/paris?zoom=15&style=dark&layer=SATELLITE সফল হয়েছে (সব প্যারামিটার প্রদান করা হয়েছে) UriMatchResult(MapKey("paris", 15, LayerOptions("dark", MapLayer.SATELLITE)))
https://www.example.com/map/paris?style=dark হয়ে গেছে (zoom ডিফল্ট হিসেবে 12-এ, layer ডিফল্ট হিসেবে STANDARD-এ সেট করা হয়েছে) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map/paris?zoom=&style=dark সফল হয়েছে (খালি ঐচ্ছিক কোয়েরি প্যারামিটার ডিফল্ট 12 ব্যবহার করে) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map?style=dark মিলছে না (প্রয়োজনীয় location প্যারামিটার নেই) null
https://www.example.com/map/paris?zoom=close&style=dark মিলছে না ("close" কোনও Int নয়) null
https://www.example.com/map/paris?style=dark&layer=HYBRID অমিল ("HYBRID" enum-এ নেই) null

কাজ করে না এমন কনফিগারেশন

আপনার কী ক্লাসে কাজ করে না এমন ডেটার ধরন থাকলে, UriDeepLinkMatcher null ফিরিয়ে দেওয়ার পরিবর্তে ম্যাচ করার সময় ব্যতিক্রম দেখায়।

  • ম্যাপ এবং মাল্টি-ডাইমেনশনাল কালেকশন: UriDeepLinkMatcher শুধুমাত্র প্রিমিটিভ, স্ট্রিং, enum বা DeepLinkSerializer-এর সাথে অ্যানোটেট করা কাস্টম ধরনের সিঙ্গেল-ডাইমেনশনাল কালেকশন সাপোর্ট করে। Map ধরনের থ্রো একটি IllegalArgumentException, যেখানে নেস্টেড কালেকশন (যেমন List<List<String>>) একটি SerializationException থ্রো করে।
  • অ্যানোটেট না করা কাস্টম অবজেক্ট কালেকশন: কাস্টম ধরনের কালেকশন (যেমন List<Filter>) SerializationException থ্রো করে, যদি না এলিমেন্টের ধরন DeepLinkSerializer-এর সাথে অ্যানোটেট করা থাকে।
  • আনফ্ল্যাটেনড নেস্টেড ক্লাস: নেস্টেড @Serializable ক্লাসকে DeepLinkSerializer ছাড়া একটি প্লেসহোল্ডারে (যেমন ?user={user}) ম্যাপ করা যাবে না।

UriMatchResult তুলনা

UriMatchResultটি ইনস্ট্যান্স নিম্নলিখিত মাপকাঠি অনুযায়ী র‍্যাঙ্ক করা হয়েছে:

  1. MatchResult-এর ধরন: UriMatchResult-এর র‍্যাঙ্ক অন্যান্য MatchResult ধরনের থেকে বেশি।
  2. সঠিক পাথ: লিটারেল পাথ ম্যাচ, প্লেসহোল্ডার বা ওয়াইল্ডকার্ড ম্যাচের চেয়ে বেশি র‍্যাঙ্ক পায়।
  3. পাথ আর্গুমেন্ট সংখ্যা: বেশি পাথ আর্গুমেন্ট সহ ম্যাচগুলি উচ্চতর র‍্যাঙ্ক করে।
  4. আর্গুমেন্টের উপস্থিতি: আর্গুমেন্ট ক্যাপচার করে এমন ম্যাচগুলি যেগুলি করে না সেগুলির চেয়ে বেশি র‍্যাঙ্ক করে।
  5. মোট আর্গুমেন্টের সংখ্যা: মোট আর্গুমেন্টের সংখ্যা (পাথ, কোয়েরি, ফ্র্যাগমেন্ট) হল চূড়ান্ত টাই-ব্রেকার।

UriDeepLinkMatcher কাস্টমাইজ করুন

UriDeepLinkMatcher হল একটি open ক্লাস যা আপনি URI ম্যাচিং এবং আর্গুমেন্ট এক্সট্র্যাকশন আচরণ কাস্টমাইজ করতে সাবক্লাস করতে পারেন:

  • matchRequest: ইনকামিং DeepLinkRequest-এর জন্য টপ-লেভেল ম্যাচিং এন্ট্রি পয়েন্ট। URI ম্যাচ করার আগে অনুরোধের অতিরিক্ত তথ্য পরীক্ষা করতে বা কাস্টম পূর্বশর্ত প্রয়োগ করতে এটি ওভাররাইড করুন।
  • matchUri: কনফিগার করা প্যাটার্নের সাথে DeepLinkUri ম্যাচ করে। super.matchUri কল করার আগে ইনকামিং URI ইন্টারসেপ্ট ও নরমালাইজ করতে (যেমন, ডায়নামিক সাবডোমেন বা লিগ্যাসি পাথ ফর্ম্যাট আবার লেখা) এটি ওভাররাইড করুন।
  • matchArguments: এক্সট্র্যাক্ট করা পাথ, কোয়েরি ও ফ্র্যাগমেন্ট আর্গুমেন্ট ম্যাপকে প্রদান করা serializer ব্যবহার করে নেভিগেশন কী ইনস্ট্যান্সে ডিসিরিয়ালাইজ করে। কী ইনস্ট্যান্টিয়েশনের আগে ডায়নামিক ভ্যালু ইনজেক্ট করতে বা আর্গুমেন্ট ট্রান্সফর্ম করতে এটি ওভাররাইড করুন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে যে কীভাবে ম্যাচ করার আগে লিগ্যাসি URL পাথ প্রিফিক্স নরমালাইজ করতে UriDeepLinkMatcher সাবক্লাস করা হয়: