রেকমেন্ডেড হাই-লেভেল ডিজাইন এবং সম্মতি গ্রহণ (Propose High-Level Design and Get Buy-In)
এই অংশে আমরা আলোচনা করব:
API design
Data models
High-level design
API design
আমরা হোটেল রিজার্ভেশন সিস্টেমের API design নিয়ে আলোচনা করি। সবচেয়ে গুরুত্বপূর্ণ API-গুলো নিচে RESTful conventions অনুসরণ করে দেওয়া হলো।
নোট করুন যে এই অধ্যায়টি একটি hotel reservation system-এর design-এর ওপর ফোকাস করে। একটি সম্পূর্ণ hotel website-এর জন্য design-এ গ্রাহকদের জন্য বিভিন্ন criteria-এর ভিত্তিতে room search করার সহজবোধ্য ফিচার থাকতে হবে। এই search feature-গুলোর API গুরুত্বপূর্ণ হলেও, সেগুলো technicalভাবে খুব চ্যালেঞ্জিং নয়। তাই এগুলো এই অধ্যায়ের scope-এর বাইরে।
Hotel-related APIs
API Detail GET /v1/hotels/ID একটি hotel-এর বিস্তারিত তথ্য দেখায়। POST /v1/hotels নতুন hotel যোগ করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ। PUT /v1/hotels/ID hotel information আপডেট করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ। DELETE /v1/hotels/ID একটি hotel delete করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ।
Table 1 Hotel-related APIs
Room-related APIs
API Detail GET /v1/hotels/ID/rooms/ID একটি room-এর বিস্তারিত তথ্য দেখায়। POST /v1/hotels/ID/rooms একটি room যোগ করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ। PUT /v1/hotels/ID/rooms/ID room information আপডেট করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ। DELETE /v1/hotels/ID/rooms/ID একটি room delete করে। এই API শুধুমাত্র hotel staff-এর জন্য উপলব্ধ।
Table 2 Room-related APIs
Reservation related APIs
API Detail GET /v1/reservations logged-in user-এর reservation history দেখায়। GET /v1/reservations/ID একটি reservation-এর বিস্তারিত তথ্য দেখায়। POST /v1/reservations নতুন reservation তৈরি করে। DELETE /v1/reservations/ID একটি reservation cancel করে।
Table 3 Reservation-related APIs
নতুন reservation তৈরি করা খুবই গুরুত্বপূর্ণ একটি feature। নতুন reservation তৈরির request parameters (POST /v1/reservations) এমন হতে পারে:
{
"startDate":"2021-04-28",
"endDate":"2021-04-30",
"hotelID":"245",
"roomID":"U12354673389",
"reservationID":"13422445"
}দয়া করে লক্ষ্য করুন, reservationID কে idempotency key হিসেবে ব্যবহার করা হয় double booking প্রতিরোধ করার জন্য। Double booking মানে একই room-এর জন্য একই দিনে একাধিক reservation তৈরি হয়ে যাওয়া। এর বিস্তারিত “Concurrency issue” অংশে ‘Deep Dive’ সেকশনে ব্যাখ্যা করা হয়েছে।
Data model
কোন database ব্যবহার করা হবে তা সিদ্ধান্ত নেওয়ার আগে, data access pattern ভালোভাবে দেখা দরকার। Hotel reservation system-এর জন্য আমাদের নিচের query-গুলো সাপোর্ট করতে হবে:
Query 1: একটি hotel-এর বিস্তারিত তথ্য দেখা।
Query 2: একটি date range দিলে available room type খুঁজে বের করা।
Query 3: একটি reservation রেকর্ড করা।
Query 4: একটি reservation বা আগের reservation history খুঁজে দেখা।
Back-of-the-envelope estimation থেকে আমরা জানি system-এর scale খুব বড় নয়, তবে বড় event-এর সময় traffic surge-এর জন্য প্রস্তুত থাকতে হবে। এই requirements মাথায় রেখে আমরা relational database বেছে নিই, কারণ:
Relational database read-heavy এবং write কম হওয়া workflow-এ ভালো কাজ করে। কারণ hotel website/app ভিজিট করা ব্যবহারকারীর সংখ্যা আসল reservation করা ব্যবহারকারীর তুলনায় কয়েক order of magnitude বেশি। NoSQL databases সাধারণত writes-এর জন্য optimized, আর relational database read-heavy workflow-এর জন্য যথেষ্ট ভালো কাজ করে।
Relational database ACID (atomicity, consistency, isolation, durability) guarantees দেয়। Reservation system-এর জন্য ACID properties খুবই গুরুত্বপূর্ণ। এগুলো না থাকলে negative balance, double charge, double reservation ইত্যাদি সমস্যা প্রতিরোধ করা কঠিন হয়ে যায়। ACID properties application code অনেক সহজ করে এবং পুরো system-কে reason করা সহজ করে। সাধারণত relational database এই guarantees দেয়।
Relational database সহজেই data model করতে পারে। Business data-এর structure খুব পরিষ্কার, এবং hotel, room, room_type ইত্যাদি entity-গুলোর relationship স্থির। এ ধরনের data model relational database-এ সহজেই model করা যায়।
এখন যেহেতু relational database কে data store হিসেবে বেছে নেওয়া হয়েছে, আসুন schema design দেখি। Figure 2-এ একটি straightforward schema design দেখানো হয়েছে এবং অনেক candidate-এর জন্য hotel reservation system model করার সবচেয়ে natural উপায় এটি।
Figure 2 Database schema
এই diagram-এ একটি hotel reservation system-এর database schema design Entity-Relationship diagram আকারে দেখানো হয়েছে। চারটি service দেখানো হয়েছে: ‘Hotel Service,’ ‘Rate Service,’ ‘Guest Service,’ এবং ‘Reservation Service.’ প্রতিটি service-এর একটি table আছে।
‘Hotel Service’-এ একটি hotel table আছে, যার attributes:
- hotel_id (primary key, PK)
- name
- address
- location
‘Rate Service’-এ একটি room_type_rate table আছে, যার attributes:
- hotel_id (PK)
- date (PK)
- rate
‘Guest Service’-এ একটি guest table আছে, যার attributes:
- guest_id (PK)
- first_name
- last_name
শেষে, ‘Reservation Service’-এ একটি reservation table আছে, যার attributes:
- reservation_id (PK)
- hotel_id
- room_id
- start_date
- end_date
- status
- guest_id
এই diagram-এ table-গুলোর মধ্যে relationship shared attribute names যেমন hotel_id, room_id, এবং guest_id-এর মাধ্যমে বোঝানো হয়েছে, যা বাস্তব database implementation-এ foreign key relationship হিসেবে explicitly define করতে হবে। টেবিলগুলোর মধ্যে explicit connection আঁকা হয়নি, তবে shared attributes relationship বোঝায়।
Figure 2 Database schema
বেশিরভাগ attribute-ই সহজবোধ্য, তাই আমরা reservation table-এর status field-টি আলাদাভাবে ব্যাখ্যা করব। status field নিচের অবস্থাগুলোর যেকোনো একটিতে থাকতে পারে:
- pending
- paid
- refunded
- canceled
- rejected
এই state machine Figure 3-এ দেখানো হয়েছে।
Figure 3 Reservation status
এই schema design-এ একটি বড় সমস্যা আছে। এই data model Airbnb-এর মতো company-র জন্য কাজ করে, যেখানে user reservation করার সময় room_id (যা listing_id-ও হতে পারে) পায়। কিন্তু hotel-এর ক্ষেত্রে তা হয় না। User আসলে নির্দিষ্ট room নয়, বরং একটি hotel-এর ভেতরে একটি নির্দিষ্ট room type reserve করে। উদাহরণস্বরূপ room type হতে পারে standard room, king-size room, queen-size room with two queen beds, ইত্যাদি। Guest check-in করার সময় room number দেওয়া হয়, reservation করার সময় নয়। এই নতুন requirement reflect করার জন্য আমাদের data model আপডেট করতে হবে। আরও বিস্তারিত জানতে ‘Deep Dive’ section-এর “Improved data model” দেখুন।
High-level design
এই hotel reservation system-এর জন্য আমরা microservice architecture ব্যবহার করি। গত কয়েক বছরে microservice architecture খুবই জনপ্রিয় হয়েছে। যে কোম্পানিগুলো microservice ব্যবহার করে তাদের মধ্যে আছে Amazon, Netflix, Uber, Airbnb, Twitter, ইত্যাদি। আপনি microservice architecture-এর সুবিধা সম্পর্কে আরও জানতে কিছু ভালো resource [1] [2] দেখতে পারেন।
আমাদের design microservice architecture-এর ওপর ভিত্তি করে তৈরি, এবং high-level design diagram Figure 4-এ দেখানো হয়েছে।
Figure 4 High-level design
এই diagram-এ একটি hotel booking system-এর system architecture দেখানো হয়েছে। Diagram-টি external এবং internal দুই ভাগে বিভক্ত, মাঝখানে একটি horizontal line দিয়ে আলাদা করা হয়েছে।
External side-এ user-এর mobile device একটি CDN (Content Delivery Network)-এর সাথে interact করে, যা পরে একটি Public API Gateway-এর সাথে সংযুক্ত হয়। এই gateway central point হিসেবে কাজ করে এবং request-গুলো চারটি distinct service-এ distribute করে:
- Hotel Service
- Rate Service
- Reservation Service
- Payment Service
এই service-গুলোর প্রতিটির own database আছে:
- Hotel DB
- Rate DB
- Reservation DB
- Payment DB
Hotel Service আরও ভালো performance-এর জন্য Hotel Cache ব্যবহার করে।
Internal, private side-এ একজন Admin user একটি Internal API-এর সাথে interact করে, যা Hotel Management Service-এর সাথে সংযুক্ত থাকে।
এই arrows component-গুলোর মধ্যে information এবং request flow দেখায়। System-টি hotel information, rates, reservations, এবং payments handling-এর জন্য তৈরি, পাশাপাশি hotel data manage করার জন্য একটি administrative interface-ও প্রদান করে।
এখন আমরা system-এর প্রতিটি component সংক্ষেপে top to bottom দেখে নিই।
User: একজন user mobile phone বা computer ব্যবহার করে hotel room book করে।
Admin (hotel staff): authorized hotel staff refund করা, reservation cancel করা, room information update করা ইত্যাদি administrative operation করে।
CDN (content delivery network): load time উন্নত করতে CDN সব static asset cache করে, যার মধ্যে JavaScript bundles, images, videos, HTML, ইত্যাদি অন্তর্ভুক্ত।
Public API Gateway: এটি একটি fully managed service যা rate limiting, authentication, ইত্যাদি support করে। API gateway endpoint-এর ভিত্তিতে নির্দিষ্ট service-এ request route করার জন্য configure করা থাকে। উদাহরণস্বরূপ, hotel homepage load করার request hotel service-এ যায়, আর hotel room book করার request reservation service-এ route হয়।
Internal APIs: এই API-গুলো শুধুমাত্র authorized hotel staff-এর জন্য উপলব্ধ। এগুলো internal software বা website-এর মাধ্যমে access করা যায়। সাধারণত এগুলো আরও বেশি সুরক্ষিত থাকে VPN (virtual private network)-এর মাধ্যমে।
Hotel Service: এটি hotel এবং room সম্পর্কে বিস্তারিত তথ্য দেয়। Hotel এবং room data সাধারণত static, তাই সহজেই cache করা যায়।
Rate Service: এটি ভবিষ্যতের বিভিন্ন date-এর জন্য room rate প্রদান করে। Hotel industry-তে interesting একটি বিষয় হলো, room-এর দাম নির্ভর করে নির্দিষ্ট দিনে hotel কতটা full হওয়ার আশা করা হচ্ছে তার ওপর।
Reservation Service: এটি reservation request গ্রহণ করে এবং hotel room reserve করে। এই service room reserve হওয়া বা reservation cancel হওয়ার সাথে room inventory-ও track করে।
Payment Service: এটি customer-এর payment execute করে এবং payment transaction সফল হলে reservation status কে “paid” এ update করে, আর transaction fail হলে “rejected” করে।
Hotel Management Service: এটি শুধুমাত্র authorized hotel staff-এর জন্য উপলব্ধ। Hotel staff-এর জন্য যেসব feature থাকে তার মধ্যে আছে:
- upcoming reservation-এর record দেখা
- customer-এর জন্য room reserve করা
- reservation cancel করা
- ইত্যাদি
স্পষ্টতার জন্য Figure 4-এ microservice-গুলোর মধ্যে অনেক interaction arrow দেখানো হয়নি। উদাহরণস্বরূপ, Figure 5-এ যেমন দেখানো হয়েছে, Reservation service এবং Rate service-এর মধ্যে একটি arrow থাকা উচিত। Reservation service room rate জানতে Rate service-কে query করে। এটি একটি reservation-এর total room charge হিসাব করতে ব্যবহৃত হয়। আরেকটি উদাহরণ হলো, Hotel Management Service-এর সাথে অন্য বেশিরভাগ service-এর অনেক arrow থাকা উচিত। যখন কোনো admin Hotel Management Service-এর মাধ্যমে পরিবর্তন করে, তখন সেই request-গুলো ডেটার মালিক service-এ forward করা হয়, যাতে পরিবর্তনটি handle করা যায়।
Figure 5 Connections between services
এই diagram-এ দুটি আলাদা service architecture দেখানো হয়েছে।
বাম পাশে একটি simple two-service architecture আছে, যেখানে Reservation Service সরাসরি Rate Service-কে তথ্যের জন্য call করে। দুইটি rectangular box-কে যুক্ত করা একটি downward arrow এটি দেখাচ্ছে।
ডান পাশে একটি আরও জটিল microservices-based architecture দেখানো হয়েছে। এখানে একটি central Hotel Management Service orchestrator হিসেবে কাজ করে এবং বিভিন্ন subordinate service-এ request distribute করে। Hotel Management Service থেকে চারটি service-এ arrow গেছে:
- Hotel Service
- Rate Service
- Reservation Service
- এবং একটি ellipsis (…) যা আরও কিছু unspecified service বোঝায়
এটি একটি client-server relationship দেখায়, যেখানে Hotel Management Service central control point হিসেবে কাজ করে এবং specialized task delegate করে। বাম পাশের simple direct interaction-এর সঙ্গে এর পার্থক্য এখানে স্পষ্ট।
এই diagram monolithic (বাম) এবং microservices (ডান) system design-এর পার্থক্য দেখায়।
Production system-এ inter-service communication-এ সাধারণত gRPC-এর মতো modern এবং high-performance remote procedure call (RPC) framework ব্যবহার করা হয়। এ ধরনের framework ব্যবহার করার অনেক সুবিধা আছে। বিশেষ করে gRPC সম্পর্কে আরও জানতে চাইলে [3] দেখুন।