---
title: Separate Parsing From Handlers
impact: HIGH
impactDescription: keeps handlers thin and focused
tags: handler, parsing, transformation, patterns, quality
---

## Separate Parsing From Handlers

Handlers (controllers) should be thin - only handling HTTP concerns. Transformation logic should be extracted.

**Incorrect (transformation in handler):**

```go
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
    user, _ := userService.FindByID(r.URL.Query().Get("id"))
    
    // Transformation logic in handler
    response := map[string]any{
        "id":        user.ID,
        "full_name": user.FirstName + " " + user.LastName,
        "email":     strings.ToLower(user.Email),
        "created_at": user.CreatedAt.Format("2006-01-02"),
    }
    
    json.NewEncoder(w).Encode(response)
}
```

**Correct (separate mapper/DTO):**

```go
type UserResponse struct {
    ID        string `json:"id"`
    FullName  string `json:"full_name"`
    Email     string `json:"email"`
    CreatedAt string `json:"created_at"`
}

func ToUserResponse(user *User) UserResponse {
    return UserResponse{
        ID:        user.ID,
        FullName:  user.FirstName + " " + user.LastName,
        Email:     strings.ToLower(user.Email),
        CreatedAt: user.CreatedAt.Format("2006-01-02"),
    }
}

// Clean handler
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
    user, _ := userService.FindByID(r.URL.Query().Get("id"))
    json.NewEncoder(w).Encode(ToUserResponse(user))
}
```

**Benefits:**
- Reusable transformation logic
- Testable mappers
- Clean handlers
- Consistent response format

**Tools:** Code review, Architecture rules
