# 07 - Router Layer (`app/routers/tenant.py`)

Is document me hum `app/routers/tenant.py` file ko line-by-line samjhenge aur dekhenge ki FastAPI routing, status codes, aur HTTP exceptions kaise handle karti hai.

---

## 1. What is an APIRouter? (The "WHY")

Badi Web Applications me saare endpoints ek single file me nahi rakhe ja sakte.

### Solution: `APIRouter`
FastAPI me `APIRouter` endpoints ko modular components me divide karne deta hai:
- `tenant.py` handles `/api/v1/tenant/*` routes.
- Later, `session.py` will handle `/api/v1/session/*` routes.
- `main.py` simply mounts these routers together.

---

## 2. Line-by-Line Code Breakdown of `tenant.py`

Here is the exact implementation in `app/routers/tenant.py`:

```python
 1: from fastapi import APIRouter, status, HTTPException
 2: from app.models.tenant import TenantCreate, TenantResponse
 3: from app.repositories.tenant_repository import create_tenant, get_tenant_by_domain
 4: from app.database import get_database
 5: 
 6: router = APIRouter(prefix="/api/v1/tenant", tags=["tenant"])
 7: 
 8: @router.post("/register", response_model=TenantResponse, status_code=status.HTTP_201_CREATED)
 9: async def register_tenant(tenant_in: TenantCreate):
10:     db = get_database()
11:     
12:     # Check if domain is already registered
13:     existing_tenant = await get_tenant_by_domain(db, tenant_in.domain)
14:     if existing_tenant:
15:         raise HTTPException(
16:             status_code=status.HTTP_400_BAD_REQUEST,
17:             detail=f"Tenant already registered for domain '{tenant_in.domain}'"
18:         )
19:     
20:     tenant_doc = await create_tenant(db, tenant_in)
21:     return tenant_doc
```

---

### Line 6: `APIRouter` Initialization
```python
router = APIRouter(prefix="/api/v1/tenant", tags=["tenant"])
```
- `prefix="/api/v1/tenant"`: Is router ke saare endpoints path prefix `/api/v1/tenant` se start honge.
- `tags=["tenant"]`: Swagger UI documentation (`/docs`) me endpoints ko "tenant" category under group karega.

---

### Line 8: Endpoint Decorator
```python
@router.post("/register", response_model=TenantResponse, status_code=status.HTTP_201_CREATED)
```
- `@router.post("/register")`: HTTP `POST` requests to `/api/v1/tenant/register` hit this function.
- `response_model=TenantResponse`: Automatically filters and formats the returned dictionary into `TenantResponse` schema.
- `status_code=status.HTTP_201_CREATED`: Success status set to `201 Created` (REST best practice for resources created on server).

---

### Line 9: Endpoint Function Definition
```python
async def register_tenant(tenant_in: TenantCreate):
```
- `tenant_in: TenantCreate`: FastAPI JSON request body read karti hai, validation and cleaning perform karti hai (`clean_domain`), aur input ko `tenant_in` argument me pass kar deti hai.

---

### Line 10-18: Database Get & Duplicate Domain Check
```python
    db = get_database()
    
    existing_tenant = await get_tenant_by_domain(db, tenant_in.domain)
    if existing_tenant:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Tenant already registered for domain '{tenant_in.domain}'"
        )
```
1. `get_database()`: Database object fetch karta hai.
2. `get_tenant_by_domain`: Database search karta hai check karne ke liye ki kya ye domain pehle se exists karta hai.
3. `raise HTTPException(...)`: Agar domain duplicate hai, execution immediately stop hota hai aur client ko `400 Bad Request` error message JSON format me return hota hai.

---

### Line 20-21: Creation & Response Return
```python
    tenant_doc = await create_tenant(db, tenant_in)
    return tenant_doc
```
1. `create_tenant`: Calls repository layer to insert document into MongoDB.
2. `return tenant_doc`: Returns the created document dictionary. FastAPI automatically casts this dictionary into `TenantResponse` (filtering out `_id`) and returns JSON to the client with `201 Created` status code.

---

## 3. Summary Checkpoint
- `APIRouter` organizes endpoint groups cleanly.
- `response_model=TenantResponse` formats output automatically.
- `HTTPException` returns HTTP error codes cleanly without crashing the server.
