আজকের পোস্টে, আমরা শিখব কিভাবে একটি Rails অ্যাপ তৈরি করতে হয় যা একাধিক সাবডোমেন সমর্থন করতে পারে। ধরা যাক আমাদের একটি গেমিং ওয়েবসাইট funkygames.co
আছে এবং আমরা একাধিক সাবডোমেন সমর্থন করতে চাই যেমন app.funkygames.co
, api.funkygames.co
, এবং dev.funkygames.co
একটি একক রেল অ্যাপ্লিকেশন সহ। আমরা নিশ্চিত করতে চাই যে সমস্ত সাবডোমেনের জন্য সঠিক প্রমাণীকরণ করা হয়েছে এবং কোনও সদৃশ রুট নেই৷
আমরা আমাদের অ্যাপ্লিকেশনে একাধিক সাবডোমেন সমর্থন করতে Rails এর শক্তিশালী রাউটিং নির্মাণ ব্যবহার করব। আমরা স্থানীয়ভাবে সাবডোমেন সেট আপ করব এবং একাধিক সাবডোমেনের জন্য পরীক্ষা লিখব।
পূর্বশর্ত
এই পোস্টের উদ্দেশ্যে, আমি অনুমান করছি যে আপনি সমস্ত সাবডোমেনের জন্য উপযুক্ত DNS রেকর্ড সেট আপ করেছেন Rails অ্যাপে নির্দেশ করার জন্য। আমরা এই পোস্টে শুধুমাত্র রেলের দিকগুলি নিয়ে কাজ করব৷
৷একাধিক সাবডোমেন পরিচালনা করা
রেল routes.rb
ব্যবহার করে ইনকামিং অনুরোধগুলি পরিচালনা করার জন্য ফাইল এবং নির্দিষ্ট নিয়ামক ক্রিয়াগুলিতে তাদের ম্যাপ করুন। একটি তুচ্ছ অ্যাপে, routes.rb
-এ প্রতিটি ম্যাপিং নিম্নরূপ একটি নিয়ামক কর্মের একটি রুট ম্যাপ করে:
get '/games/:id', to: 'games#show'
এই পদ্ধতির সাথে, আমাদের routes.rb
-এ সংজ্ঞায়িত সমস্ত শেষ পয়েন্ট ফাইল সব সাবডোমেনের জন্য প্রযোজ্য। তাই app.funkygames.co/games/1
সেইসাথে api.funkygames.co/games/1
এই রুট দ্বারা পরিচালিত হবে. যাইহোক, আমরা শুধুমাত্র app
থেকে আসা অনুরোধ চাই সাবডোমেন এই রুট দ্বারা পরিচালনা করা হবে। api
সাবডোমেন শুধুমাত্র API রুটের জন্য ব্যবহার করা হবে। আমরা রুটগুলিতে কিছু নিয়ম যুক্ত করব যাতে আগত অনুরোধের জন্য একটি নির্দিষ্ট নিয়ম পূরণ হলেই সেগুলি পরিচালনা করা হয়৷
রেল রাউটিং একটি constraints
প্রদান করে সহায়ক পদ্ধতি যা প্রদত্ত রুটের জন্য অতিরিক্ত নিয়ম নির্দিষ্ট করতে পারে।
get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }
এটি নিশ্চিত করবে যে অনুরোধটি app.funkygames.co/games/1
থেকে আসছে কিনা , এটি GamesController's
দ্বারা পরিচালিত হবে৷ কর্ম দেখান app
ছাড়া অন্য সাবডোমেন থেকে যেকোনো অনুরোধ এই রুট দ্বারা পরিচালনা করা হবে না৷
constraints
সংজ্ঞায়িত করা খুবই কষ্টকর হয়ে উঠবে প্রতিটি রুটের জন্য এই মত।
get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }
get '/games/list', to: 'games#list', constraints: { subdomain: 'app' }
post '/games/start', to: 'games#start', constraints: { subdomain: 'app' }
আমরা constraints
-এর ব্লক ফর্ম ব্যবহার করতে পারি একটি একক সাবডোমেনের জন্য একাধিক রুট সংজ্ঞায়িত করতে সাহায্যকারী৷
constraints subdomain: 'app' do
get '/games/:id', to: 'games#show'
get '/games/list', to: 'games#list'
post '/games/start', to: 'games#start'
end
একাধিক সাবডোমেনের জন্য রুট সংজ্ঞায়িত করতে, আমাদের শুধু একাধিক constraints
যোগ করতে হবে আমাদের routes.rb
-এ ব্লক ফাইল।
constraints subdomain: 'app' do
...
end
constraints subdomain: 'api' do
...
end
constraints subdomain: 'dev' do
...
end
আন্ডার দ্য হুড
রেল রাউটিং অনুরোধের সীমাবদ্ধতা এবং সেগমেন্ট সীমাবদ্ধতা প্রদান করে। সেগমেন্ট সীমাবদ্ধতা অনুরোধের পথে নিয়ম যোগ করে যেখানে অনুরোধের সীমাবদ্ধতা আগত অনুরোধে শর্ত যোগ করে। অনুরোধের সীমাবদ্ধতার হ্যাশ কীটি Request
-এ একটি পদ্ধতি হওয়া দরকার বস্তু যা একটি স্ট্রিং প্রদান করে এবং মানটি প্রত্যাশিত মান হতে হবে।
constraints subdomain: 'app' do
...
end
উপরের ক্ষেত্রে, আমরা subdomain
ব্যবহার করছি Request
-এ পদ্ধতি অবজেক্ট এবং app
এর মত একটি স্ট্রিং এর সাথে মিলছে , api
অথবা dev
.
আরও বিশদ বিবরণের জন্য, রেল রাউটিং গাইড দেখুন৷
৷মাল্টি-লেভেল সাবডোমেন পরিচালনা করা
ধরা যাক আমরা app.staging.funkygames.co
ব্যবহার করছি আমাদের স্টেজিং পরিবেশের জন্য। যদি আমাদের উপরে সেটআপ থাকে, তাহলে আমরা দ্রুত লক্ষ্য করব যে সমস্ত অনুরোধগুলি app
এ আঘাত করার কথা। সাবডোমেন একটি 404 ফেরত দিচ্ছে। যদি আমরা আরও ডিবাগ করি, তাহলে আমরা লক্ষ্য করব যে সাবডোমেনের জন্য আমাদের সীমাবদ্ধতা ব্যর্থ হচ্ছে।
request.subdomain #=> app.staging
আমরা আশা করছি সাবডোমেন app
ফেরত দেবে , কিন্তু পরিবর্তে, এটি app.staging
প্রদান করে . অবশ্যই, আমরা পরিবেশ-নির্দিষ্ট কোড যোগ না করে এটি সমাধান করতে চাই! অনুরোধের সাবডোমেনের পার্সিং config.action_dispatch.tld_length
দ্বারা পরিচালিত হয় বিকল্প এই কনফিগারেশনের ডিফল্ট মান হল 1, যা মূলত সাবডোমেনের একটি স্তর সমর্থন করে। যেহেতু আমাদের দুটি স্তরের সাবডোমেন রয়েছে, তাই আমাদের config.action_dispatch.tld_length
এর মান সেট করতে হবে থেকে 2.
# config/application.rb
config.action_dispatch.tld_length = Integer(ENV['TLD_LENGTH'] || 1)
আমরা এটিকে একটি এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করে সেট করতে পারি যাতে আমরা স্টেজিং এবং উৎপাদন পরিবেশে একই কোড ব্যবহার করতে পারি। এখন, আমাদের রাউটিং সেটআপ app.staging.funkygames.co
এর জন্য কাজ করবে সেইসাথে।
সেশন ম্যানেজমেন্ট
এখন যেহেতু একাধিক সাবডোমেন থেকে আসা অনুরোধগুলি পরিচালনা করার জন্য রুটগুলি সংজ্ঞায়িত করা হয়েছে, আমাদের সমস্ত সাবডোমেনের জন্য প্রমাণীকরণের যত্ন নিতে হবে। আমরা এটি দুটি উপায়ে করতে পারি—আমরা হয় একই ব্যবহারকারী সেশনকে সমস্ত সাবডোমেন জুড়ে ব্যবহার করার অনুমতি দিতে পারি, অথবা আমাদের আলাদা সাবডোমেনের জন্য আলাদা সেশন থাকতে পারে৷
সংক্ষেপে প্রমাণীকরণ
রেল ডিফল্টরূপে ব্যবহারকারীর সেশন কী সংরক্ষণ করতে কুকিজ ব্যবহার করে। ব্যবহারকারী একবার লগ ইন করলে, ব্যবহারকারীর সেশনের তথ্য আমাদের পছন্দের সেশন স্টোরে সংরক্ষণ করা হয় এবং সেশন কী ব্রাউজারে কুকি হিসাবে সংরক্ষণ করা হয়। তাই পরের বার যখন ব্যবহারকারী আমাদের ওয়েবসাইট ভিজিট করেন, একই সেশন কুকি ব্রাউজার থেকে সার্ভারে পাঠানো হয় এবং সার্ভার সিদ্ধান্ত নেয় যে ব্যবহারকারী লগ ইন করেছে কিনা তার উপর ভিত্তি করে সেশনটি ইনকামিং সেশন কুকির জন্য বিদ্যমান কিনা।
সেশনের জন্য ডিফল্ট কনফিগারেশন Rails অ্যাপে এইরকম দেখায়:
Rails.application.config.session_store :cookie_store, key: "_funkygames_session"
কী _funkygames_session
সেশন কুকির নাম হিসেবে ব্যবহার করা হবে এবং এর মান হবে সেশন আইডি।
কুকিজ প্রাইমার
ডিফল্টরূপে, অনুরোধের ডোমেনে ব্রাউজার দ্বারা কুকি সেট করা হয়। তাই যদি আমরা app.funkygames.co
থেকে আমাদের অ্যাপ্লিকেশনটি হিট করি তারপর সেশন কুকি app.funkygames.co
এর বিপরীতে সেট করা হবে . প্রতিটি সাবডোমেন তার নিজস্ব সেশন কুকিজ সেট করবে, তাই ব্যবহারকারীর সেশন ডিফল্টরূপে সাবডোমেন জুড়ে শেয়ার করা হবে না।
বিভিন্ন সাবডোমেনের মধ্যে শেয়ারিং সেশন
আমরা যদি সাবডোমেন জুড়ে ব্যবহারকারীর সেশন ভাগ করতে চাই, তাহলে আমাদের funkygames.co
-এ সেশন কুকি সেট করতে হবে ডোমেন নিজেই যাতে সমস্ত সাবডোমেন এটি অ্যাক্সেস করতে পারে। এটি domain
পাস করে অর্জন করা যেতে পারে সেশন স্টোর সেটিংসের বিকল্প।
Rails.application.config.session_store :cookie_store, key: "_funkygames_session", domain: :all
domain
পাস করে :all
হিসাবে , আমরা মূলত Rails কে বলছি অ্যাপ্লিকেশনের টপ-লেভেল ডোমেনে যেমন funkygames.co
সেশন কুকি সেট করতে। অনুরোধ হোস্টের পরিবর্তে যার মধ্যে পৃথক সাবডোমেন অন্তর্ভুক্ত থাকতে পারে। একবার আমরা এটি করি, সেশনটি বিভিন্ন সাবডোমেনের মধ্যে ভাগ করা যেতে পারে৷
এছাড়াও আমরা
domain
-এ ডোমেনের একটি তালিকা পাঠাতে পারি একাধিক ডোমেন সমর্থন করার জন্য একটি অ্যারে বিন্যাসে বিকল্প।
আরও একটি বিকল্প রয়েছে যা সমস্ত সাবডোমেনের জন্য সঠিকভাবে কুকি সেট করার জন্য কনফিগার করা প্রয়োজন৷ এটি হল tld_length
বিকল্প domain: :all
ব্যবহার করার সময় , এই বিকল্পটি নির্দিষ্ট করতে পারে কিভাবে ডোমেনের TLD ব্যাখ্যা করতে ডোমেন পার্স করা যায়। আমাদের ক্ষেত্রে, app.funkygames.co
এর জন্য , আমাদের tld_length
সেট করা উচিত TLD কে funkygames.co
হিসাবে ব্যাখ্যা করার জন্য রেলের জন্য 2 থেকে কুকিজ সেট আপ করার সময়। তাই একাধিক সাবডোমেনের জন্য চূড়ান্ত সেশন স্টোর কনফিগারেশন এইরকম দেখাচ্ছে:
Rails.application.config.session_store :cookie_store,
key: "_funkygames_session",
domain: :all,
tld_length: 2
tld_length
সেশন স্টোরের বিকল্পconfig.action_dispatch.tld_length
থেকে আলাদা আগে আলোচনা করা হয়েছে।
একাধিক সাবডোমেনের জন্য লেখার পরীক্ষা
যেহেতু রুটগুলি সাবডোমেন নির্দিষ্ট, তাই অনুরোধের স্পেস বা ইন্টিগ্রেশন পরীক্ষার ফলাফল 404 ত্রুটির কারণ যদি পরীক্ষার অনুরোধে একটি সঠিক সাবডোমেন না থাকে। রেল ইন্টিগ্রেশন পরীক্ষা একটি host!
প্রদান করে সহায়ক যা একটি পরীক্ষা ফাইলের মধ্যে করা সমস্ত অনুরোধের জন্য উপযুক্ত সাবডোমেন সেট করতে পারে।
# Configuring subdomain in Rails integration tests
setup do
host! 'dev.example.com'
end
# # Configuring subdomain in RSpec request specs
before do
host! 'dev.example.com'
end
এর পরে, routes.rb
-এ সাবডোমেন রাউটিং অনুযায়ী অনুরোধগুলি সঠিকভাবে কন্ট্রোলার অ্যাকশনে পাঠানো হবে। ফাইল।
মনে রাখবেন যে ডোমেন এখানে কোন ব্যাপার নয়, আমরা যে কোডটি পরীক্ষা করছি তার ভিত্তিতে শুধুমাত্র সঠিক সাবডোমেনই গুরুত্বপূর্ণ।
উন্নয়নের জন্য স্থানীয়ভাবে একাধিক সাবডোমেন সেট আপ করা
স্থানীয়ভাবে সাবডোমেন সেট আপ করার একাধিক উপায় আছে। সবচেয়ে সহজ হল /etc/hosts
সম্পাদনা করা ফাইল।
127.0.0.1 dev.funkygames.local
127.0.0.1 app.funkygames.local
127.0.0.1 api.funkygames.local
এটি নিশ্চিত করে যে সাবডোমেন সেটআপ স্থানীয় পরিবেশে কাজ করবে। আমরা স্থানীয়ভাবে সাবডোমেন পরিচালনার জন্য pow-এর মতো টুলও ব্যবহার করতে পারি।
সীমাবদ্ধতা ভিত্তিক সাবডোমেন রাউটিং সহ গোটচাস
যদিও সীমাবদ্ধতা ভিত্তিক সাবডোমেন রাউটিং বেশিরভাগ ক্ষেত্রেই কাজ করে, তবে কিছু পরিস্থিতিতে এটি একটি ব্যথা হতে পারে।
বাহ্যিক API-এর সাথে ডিল করা
যখন আমরা তৃতীয় পক্ষের API এবং বিল্ডিং ইন্টিগ্রেশন নিয়ে কাজ করি, তখন স্থানীয় উন্নয়ন TLDs যেমন .local
অথবা .dev
অনুমতি দেওয়া হয় না. আমাদের এনগ্রোকের মতো সরঞ্জাম ব্যবহার করতে হবে। সাবডোমেন ভিত্তিক রাউটিং এই ধরনের ক্ষেত্রে কাজ করে না এবং আমাদের নির্দিষ্ট রুটগুলিকে সাদা তালিকাভুক্ত করতে হবে যাতে সেগুলি এনগ্রোকের মাধ্যমেও অ্যাক্সেসযোগ্য হয়৷
সাবডোমেনের সীমাবদ্ধতার বাইরের রুটগুলি
সাবডোমেন সীমাবদ্ধতার মধ্যে নির্দিষ্ট রুট স্থাপন করা যাবে না। একটি সাধারণ উদাহরণ হল healthcheck
অথবা ping
শেষ পয়েন্ট আমরা যদি আমাদের Rails অ্যাপের সামনে একটি লোড ব্যালেন্সার ব্যবহার করি, তাহলে লোড ব্যালেন্সারকে পর্যায়ক্রমে পরীক্ষা করতে হবে অ্যাপটি চালু আছে কি না। healthcheck
এই ধরনের ক্ষেত্রে ব্যবহৃত এন্ডপয়েন্ট সাবডোমেন সীমাবদ্ধতার অধীনে হতে পারে না কারণ লোড ব্যালেন্সারের সম্ভবত অনুরোধ হোস্টের জ্ঞান থাকবে না।
রুট রুটের অনুপস্থিতি
রেলের একটি বিশেষ root
আছে রুট যা মূলত অ্যাপ্লিকেশনের ডিফল্ট রুট। যদি অন্য কোনো রুট অনুরোধের সাথে মেলে না, তাহলে root
রুট ব্যবহার করা হয়। যখন আমাদের কোনো একটি সাবডোমেনের অধীনে আমাদের সমস্ত রুট থাকে, তখন এমন পরিস্থিতি হতে পারে যেখানে আমাদের কোনো root
নেই রুট একেবারেই সংজ্ঞায়িত। কিছু রত্ন একটি root
এর উপস্থিতির উপর নির্ভর করতে পারে রুট এবং সেই অনুযায়ী আমাদের চেক এবং ব্যালেন্স যোগ করতে হবে।
উপসংহার
এই পোস্টে, আমরা কনফিগারেশনের খুব কম লাইন সহ একাধিক সাবডোমেন সহ একটি রেল অ্যাপ সেট আপ করেছি। আমরা একাধিক সাবডোমেনের জন্য কার্যকর পরীক্ষা লেখার টিপস সহ স্থানীয়ভাবে পাশাপাশি বিভিন্ন পরিবেশে কীভাবে সাবডোমেন সেট আপ করতে হয় তাও দেখেছি। Rails দ্বারা সরবরাহ করা প্লাম্বিংয়ের সাথে, একাধিক সাবডোমেন সহ একটি Rails অ্যাপ সেট আপ করা এবং পরীক্ষা করা সহজ হয়ে যায়।
পি.এস. আপনি যদি রুবি ম্যাজিক পোস্টগুলি প্রেস থেকে বের হওয়ার সাথে সাথে পড়তে চান তবে আমাদের রুবি ম্যাজিক নিউজলেটারে সাবস্ক্রাইব করুন এবং একটি পোস্ট মিস করবেন না!