deployment concept
Service API
api.png
employee-actions.png
guest-actions.png
API Testbed
REST API Guideliness
Endpoint Naming
All endpoints under /BusinessAPI/, reserve /ManagementAPI for Hotel management console should there be one, hence prefering [Verb]/[Noun]
over [Noun]/[Verb]
, the latter being more suitable to /ManagementAPI
- e.g.
/reserve/room
not /room/reserve
- why:
- a
reserve
might operate on tables other than room
only
- for a hotel business,
actions
are more intuitive.
- easier to extend from
/query/order/room
(search by room) to /query/order/guest
(search by guest)
Concurrrency and scalability
Modern hardware are typically powerful enough to process a single synchronous data flow from the frontend to database and back in a fast enough manner. Meanwhile, It's easy to setup several docker instance of of the web API behind a load balance NGINX server even on a single box. This design favors multiple instance scalability than in app concurrency. All APIs are sync calls unless later benchmark demands a shift to TPL etc.
Data Race
Race are left to MongoDB servers as much as possible. Business states(reservation, order etc.) are persisted as MongoDB collections. So that WebAPI servers are stateless, making it easier to scale up.
- Leverage MongoDB's multi-level atomic features to hold the source of truth.
- Adopt multi-document transactionswhen necessary
- Prefer
Aggregation Pipeline Stages
to multiple API calling
- Leveraging document operation atomicity when design DB schema, prefer atomic record design
- Order, Reservation entries are
per night per guest per room
,
- e.g. if a guest reserves/Orders 5 days, them 5 entries are created atomically
- This atomicity of entries makes reservation canceling easy to handle, and mid-order checkout, mid-order room changes .
- less race condition
- agile business logic, i.e. single entry/document CRUD operations.
- MongoServer instance
- per official documentation, it's advised to keep only one connection, and the driver would manage the pooling and lifetime.
Data Types
- _id
- Dates
ints
of YYYYMMDDHH
by default
- e.g. 2019050113 stands for 2019-05-01 13:00-13:59 local time.
- For event timestamps, use system datetime type
- Price
- always store amount and a currency name together
- Ranges
- exclusive, unless explicitly stated.
- prices
- dates
HTTP Verbs
- GET for query
- POST for DB document creation
- PUT for DB document update
- DELETE for DB document deletion
- not used yet, no document deleted from DB, instead marked.
- could be useful possible companion /MaintenanceApi/ api set.
Main Models
Each model corresponds to a MongoDB collection.
Main Controllers
Main Service
- MongoService
- workhorse of MongoDB op-erations
- per official suggestion, only one MongoDB client is created and share acroos the application, it's drive manages the pool and life time
- MaintenanceService
- maintenance that needs to run periodically, i.e. not event-driven by the controllers
- e.g. cleaning up no-show reservations every midnight
- PaymentService
- manage 3rd-party(banks, paypal, alipay etc.) payments.
REST API Documentaion [to be completed]
- request
- GET /api/query/roomtype
- parameters:
- type : room type
- lower: lower bound of room price
- higher: higher bound of room price
- start: first day(inclusive)
- end: last day(inclusive)
- example:
- https://localhost:44374/BusinessApi/query/roomtype?type=Any&lower=100&higher=300&start=2019-04-28&end=2019-04-29
- response
- code 200
- Json body
- Example:
- [
{
"id": "6acb7b31e10646dfb9db67805cb03ef4",
"name": "Room 100",
"type": "double",
"status": "available",
"price": 500,
"currency": "USD",
"images": [
"bed.jpg",
"house.jpg",
"bathroom.jpg",
"TV.jpg"
],
"amenities": [
"wifi",
"dryer",
"cable TV"
]
},...