User Tools

Site Tools


flight_booking_bff

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
flight_booking_bff [2025/12/31 09:14] – [Business Logging Example] pradnyaflight_booking_bff [2026/01/24 05:44] (current) – [Error Handling Strategy] madan
Line 15: Line 15:
 ==== Key Services / Core Components ==== ==== Key Services / Core Components ====
  
-^Service^Responsibility| +^Service^Responsibility^Local Port
-|**API Gateway / BFF (Node.js)** |Single entry point for UI| +|**API Gateway / BFF (Node.js)** |Single entry point for UI|4000
-|**Auth Service** |Issues & validates tokens| +|**Auth Service** |Issues & validates tokens|4001
-|**Flight Service** |Calls supplier API + Redis cache| +|**Flight Service** |Calls supplier API + Redis cache|4002
-|**Booking Service (MySQL)** |Stores booking data| +|**Booking Service (MySQL)** |Stores booking data|4003
-|**Payment Service** |Payment initiation + webhooks|+|**Payment Service** |Payment initiation + webhooks|4004| 
  
 ==== Observability Stack ==== ==== Observability Stack ====
Line 29: Line 30:
   * **Cloud Logging (ELK / CloudWatch / Loki)**   * **Cloud Logging (ELK / CloudWatch / Loki)**
 === Token Flow Diagram === === Token Flow Diagram ===
- 
 <code> <code>
 +
 [Frontend] → login → [Auth Service] \ [Frontend] → login → [Auth Service] \
            ← JWT Token \            ← JWT Token \
Line 38: Line 39:
  
 Tokens are validated per request. Tokens are validated per request.
- 
  
 ==== Flight Caching Strategy (Redis — 5 mins TTL) ==== ==== Flight Caching Strategy (Redis — 5 mins TTL) ====
Line 70: Line 70:
  
 </code> </code>
- 
  
 ===== Node.js Folder Structure (Clean Architecture) ===== ===== Node.js Folder Structure (Clean Architecture) =====
  
 +^Layer^Purpose^Examples^Should define errors?|
 +|**Domain** |Business rules|Entities, aggregates|**Business errors ** |
 +|**Domain/Application** |Use-cases / orchestration|Services, DTOs|**App errors ** |
 +|**Infrastructure** |Technical adapters|DB, Redis, HTTP|**Adapter-only errors ** |
 +|**Interface/API** |Controllers|REST/GraphQL|no core errors|
 <code> <code>
 +
 src/ src/
  ├ api/  ├ api/
  │   ├ controllers/  │   ├ controllers/
  │   ├ routes/  │   ├ routes/
- │   └ middlewares/+ │   ├ middlewares
 + │   └ errors/
  ├ domain/  ├ domain/
  │   ├ entities/  │   ├ entities/
  │   ├ services/  │   ├ services/
- │   └ repositories/+ │   ├ repositories
 + │   └ errors/
  ├ infrastructure/  ├ infrastructure/
  │   ├ db/  │   ├ db/
  │   ├ redis/  │   ├ redis/
  │   ├ logger/  │   ├ logger/
- │   └ http/+ │   ├ http
 + │   └ errors/
  └ tests/  └ tests/
  
 </code> </code>
 +
 +
 +
  
 ===== MySQL — Connection Pool ===== ===== MySQL — Connection Pool =====
Line 328: Line 339:
       * trace id       * trace id
   * Support dashboards & SLIs   * Support dashboards & SLIs
- 
  
 ===== Correlation ID Strategy ===== ===== Correlation ID Strategy =====
Line 368: Line 378:
 ==== Required JSON Fields ==== ==== Required JSON Fields ====
  <font 9px/inherit;;inherit;;inherit>bash</font>  <font 9px/inherit;;inherit;;inherit>bash</font>
- 
 <code> <code>
 +
 timestamp timestamp
 service service
Line 384: Line 394:
  
 </code> </code>
- 
  
 ===== Pino Implementation ===== ===== Pino Implementation =====
Line 391: Line 400:
  <font 9px/inherit;;inherit;;inherit>bash</font>  <font 9px/inherit;;inherit;;inherit>bash</font>
  
-<code>npm i pino pino-http pino-pretty+<code> 
 +npm i pino pino-http pino-pretty 
 </code> </code>
  
Line 410: Line 421:
  
 </code> </code>
- 
  
 ==== HTTP Logger ( /src/infrastructure/logger/http-logger.ts ) ==== ==== HTTP Logger ( /src/infrastructure/logger/http-logger.ts ) ====
  <font 9px/inherit;;inherit;;inherit>ts</font>  <font 9px/inherit;;inherit;;inherit>ts</font>
- 
 <code> <code>
  
Line 431: Line 440:
  
 </code> </code>
- 
  
 ==== Express Usage ==== ==== Express Usage ====
  <font 9px/inherit;;inherit;;inherit>ts</font>  <font 9px/inherit;;inherit;;inherit>ts</font>
- 
 <code> <code>
  
Line 446: Line 453:
  
 </code> </code>
- 
  
 ==== Business Logging Example ==== ==== Business Logging Example ====
Line 459: Line 465:
  
 </code> </code>
- 
  
 ==== OpenTelemetry Tracing ==== ==== OpenTelemetry Tracing ====
Line 467: Line 472:
   * traceId   * traceId
   * spanId   * spanId
- 
  
 ==== Benefits ==== ==== Benefits ====
Line 475: Line 479:
   * error attribution   * error attribution
  
-<code>Code to link trace → logs → DB query+<code> 
 +Code to link trace → logs → DB query 
 </code> </code>
  
Line 498: Line 504:
  
 </code> </code>
 +
 +====== Error Handling Strategy ======
 +
 +**1. Client Errors (4xx)**
 +
 +^Code^Meaning|
 +|400|Bad Request/validation failure|
 +|401|unauthorized|
 +|404|cache expired|
 +|409|idempotency conflict|
 +|500|internal error|
 +
 +**2. Server Errors (5xx)**
 +
 +^Type^Source^Action|
 +|Dependency Failure|Redis/MySQL|Retry / Circuit Breaker|
 +|Timeout|3rd-party API|Fail fast|
 +|Internal Crash|unexpected bug|Log & alert|
 +
 +**3. Business Errors**
 +
 +^Example^Handling|
 +|Flight unavailable|409|
 +|Payment declined|422|
 +|Invalid state transition|409|
 +
 +===== Recommended Placement =====
 +
 +**1. ****Business / Domain Errors**
 +
 +When business rule is violeted -
 + <font inherit/inherit;;inherit;;#dddddd>/src/domain/errors</font>
 + <font 9px/inherit;;inherit;;inherit>ts</font>
 +
 +<code>
 +export class FlightUnavailableError extends Error {
 +  code = 'FLIGHT_UNAVAILABLE';
 +}
 +
 +</code>
 +
 +**2. ****Application Errors**
 +
 +Use-case level\\
 +Validation / workflow / orchestration
 +
 +/src/application/errors
 + <font 9px/inherit;;inherit;;inherit>ts</font>
 +
 +<code>
 +export class ValidationError extends Error {
 +  status = 400;
 +  code = 'VALIDATION_ERROR';
 +}
 +
 +</code>
 +
 +**3. ****Infrastructure Errors**
 +
 +ONLY for wrapping technical failures
 +
 +/src/infrastructure/errors
 + <font 9px/inherit;;inherit;;inherit>ts</font>
 +
 +<code>
 +export class RedisConnectionError extends Error {
 +  code = 'REDIS_CONNECTION_ERROR';
 +}
 +
 +</code>
 +
 +BUT — these should usually be **mapped upward** into application-level errors.
 +
 +Example mapping:
 + <font 9px/inherit;;inherit;;inherit>ts</font>
 +
 +<code>
 +try {
 +   await redis.get(key);
 +} catch(e) {
 +   throw new CacheUnavailableError();
 +}
 +
 +</code>
 +
 +So the **API layer never leaks Redis internals.**
 +
 +
 +===== Error Flow (Best Practice) =====
 +
 +<code>
 +Infrastructure error
 +   ⬇ wrap / map
 +Application error
 +   ⬇ serialized to client
 +HTTP response
 +
 +</code>
 +
 +final structure should look like
 +
 +<code>
 +/src
 + ┣ /domain
 + ┃   ┗ /errors   ← Business rule errors
 + ┣ /application
 + ┃   ┗ /errors   ← Validation + workflow errors
 + ┣ /infrastructure
 + ┃   ┗ /errors   ← Technical adapter errors (wrapped)
 + ┗ /api (interfaces)
 +     ┗ error-middleware.ts  ← converts to HTTP response
 +
 +</code>
 +
 +**What to AVOID**
 +
 +Defining all errors in ''infrastructure'' \\
 +→ couples business logic to technology
 +
 +Throwing raw DB/Redis errors upward\\
 +→ leaks internal details
 +
 +Mixed styles (sometimes returning strings, sometimes errors)\\
 +→ debugging nightmare
  
  
flight_booking_bff.1767172477.txt.gz · Last modified: by pradnya