Designing a Scalable Booking .Net API – Best Practices & Input Needed
Hey everyone,
I’m working on designing a mock booking hotels/flights API, and I want to know your go-to best practices, design patterns, and scalable architecture.
This API will allow users to search, book and check status.
The system should support different search types
No external database – all data should be stored in-memory for now.
Bookings take time to process, so users need to wait 30-60s for a booking to be completed. They can check for status updates.
What architecture and design patterns would you use?
7 Replies
umm
Uhhh that's a lot of questions
Do you have a specific area you want to prioritize getting help on first?
I am trying to decide what is the best approach for this kind of app. I decided to go with clean architecture, I was wondering if I should use MediatR pattern or will it be an overkill for this app?
What are the goals you seek to solve with CA / MediatR in this app specifically?
Most of the peers on the server, including me, dislike CA for the added complexity
$whynotca
CA is not necessarily difficult to understand conceptually, but they're difficult to build and difficult to maintain. When you build a real project, you will quickly (as often evidenced on this server) run into questions like "Is this an infrastructure object or a domain object?" or "Should I implement this contract in the infrastructure or the application?". Questions that a) take your time to ponder and ultimately answer, and b) distract you from doing your actual work.
It also adds unnecessary abstractions, by forcing you to use layers: both unnecessary layers and unnecessary decoupling between layers. For example, CA would generally argue that you should abstract the database into repositories and services should depend on an interface for the repository. However, modern ORMs like EFC already implement the repository pattern, by abstracting the implementation of a query via LINQ. Furthermore, in most applications, there's only one implementation of
IXxxRepository
- so why create the interface abstraction?
Instead, it's generally better to get rid of nearly all interfaces, keeping only ones that truly have more than one implementation; simplifying maintenance because any change to an api only needs to be done in one class instead of both class and interface. Smush all of the code down into a single Web project, or possibly two: Web and Services projects; removing any questions about "which project does this class go into?". Organize your code well in the Web project, with all of the User-related services/controllers/models/etc under /Features/Users/Xxx
; all of the Order-related services/controllers/models/etc under /Features/Orders/Xxx
; etc. Then it will be easy to find and maintain all of the code related to such and such feature. Any Infrastructure code (like emails, behaviors, startup code, etc.) can go under /Infrastructure/Xxx
, and any non-infrastructure code that's not related to a feature can go under /Features/Shared
.Especially for this app CA seems like a massive overkill
This seems like a regular CRUD-like API which will not be an issue that needs abstractions for solving it
For the wait part, you could have the client either connected via signalr or long polling to allow for near-realtime communication
this app is a small part of a large solution and I must think in advance for future extension and optimization, that's why I found implementation of MediatR to be suitable for extension
I might be wrong, what is expected from the app is to use some type of design pattern, to be optimized and to follow best practices and principles (including OOP, SOLID)