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 আর্গুমেন্টকে আদিম টাইপ, এনুম, কালেকশন ও কাস্টম অবজেক্টে ডিসিরিয়ালাইজ করতে সাহায্য করে। সিরিয়ালাইজেশনকে দুটি বিভাগে ভাগ করা যায়:

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

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

UriDeepLinkMatcher কাস্টম সিরিয়ালাইজার প্রয়োগ করার প্রয়োজন ছাড়াই স্ট্যান্ডার্ড ধরনের জন্য এবং ফ্ল্যাটেন করা স্ট্রাকচারের জন্য রেডি-টু-ইউজ হিসেবে কাজ করে।

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

UriDeepLinkMatcher অটোমেটিক আদিম ধরনের (Boolean, Int, Long, Float, Double, Char, Byte, Short) এবং String ডিকোড করে:

Enums

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

কোয়েরি কালেকশন রিপিট করা

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

নেস্ট করা @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>), DeepLinkSerializer<T>-এর জন্য এলিমেন্ট টাইপ T প্রয়োগ করুন এবং প্রপার্টির টাইপ আর্গুমেন্টকে @Serializable(with = ...) দিয়ে অ্যানোটেট করুন:

সিঙ্গেল প্যারামিটারে আলাদা করা সংগ্রহ

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

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

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

ম্যাচ না করা

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

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

ম্যাচ না করলে, UriDeepLinkMatcher.match null রিটার্ন করে, যার ফলে পরবর্তী ম্যাচ করা যায়।

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

নিচের সারণীতে বিভিন্ন অনুরোধের 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শুধুমাত্র প্রিমিটিভ, স্ট্রিং, এনুম বা 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 ম্যাচ করে। ইনকামিং URI ইন্টারসেপ্ট ও স্বাভাবিক করার জন্য এটি ওভাররাইড করুন (যেমন, ডায়নামিক সাবডোমেন বা লিগ্যাসি পাথ ফর্ম্যাট রিরাইট করা) super.matchUri কল করার আগে।
  • matchArguments: এক্সট্র্যাক্ট করা পাথ, কোয়েরি ও ফ্র্যাগমেন্ট আর্গুমেন্ট ম্যাপকে প্রদত্ত serializer ব্যবহার করে নেভিগেশন কী ইনস্ট্যান্সে ডিসিরিয়ালাইজ করে। কী ইনস্ট্যানশিয়েট করার আগে ডায়নামিক ভ্যালু ইনজেক্ট করতে বা আর্গুমেন্ট ট্রান্সফর্ম করতে এটি ওভাররাইড করুন।

ম্যাচ করার আগে UriDeepLinkMatcher সাবক্লাস করে পুরনো URL পাথ প্রিফিক্সকে স্বাভাবিক করার উদাহরণ নিচে দেওয়া হল: