Лучшие практики при работе с обработчиками
Принципы проектирования эффективных обработчиков HTTP
1. Разделение ответственности
type UserHandler struct {
service *UserService
logger *log.Logger
}
func (h *UserHandler) Create(w http.ResponseWriter, r *http.Request) {
// Clear separation between HTTP logic and business logic
user, err := h.service.CreateUser(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
json.NewEncoder(w).Encode(user)
}
Шаблоны обработки запросов
graph TD
A[Incoming Request] --> B{Validation}
B --> |Valid| C[Business Logic]
B --> |Invalid| D[Error Response]
C --> E[Response Generation]
E --> F[Send Response]
2. Стратегии обработки ошибок
Тип ошибки |
Подход к обработке |
HTTP-статус |
Валидация |
Возврат ошибки "Неверный запрос" |
400 |
Аутентификация |
"Не авторизован" |
401 |
Авторизация |
"Доступ запрещен" |
403 |
Не найдено |
"Ресурс отсутствует" |
404 |
Ошибка сервера |
"Внутренняя ошибка" |
500 |
3. Реализация промежуточного ПО (Middleware)
func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if !validateToken(token) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
}
}
Оптимизация производительности
Эффективная обработка запросов
func (h *ResourceHandler) Get(w http.ResponseWriter, r *http.Request) {
// Use context for timeout management
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
result, err := h.service.FetchResource(ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(result)
}
Вопросы безопасности
Валидация входных данных
func validateInput(input string) bool {
// Implement robust input validation
return len(input) > 0 && len(input) <= 100
}
Шаблоны параллельной обработки
Обработчики, безопасные для горутин
type SafeHandler struct {
mu sync.Mutex
resources map[string]Resource
}
func (h *SafeHandler) UpdateResource(id string, r *Resource) {
h.mu.Lock()
defer h.mu.Unlock()
h.resources[id] = *r
}
Логирование и мониторинг
Структурированное логирование
func (h *Handler) LogRequest(r *http.Request) {
log.WithFields(log.Fields{
"method": r.Method,
"path": r.URL.Path,
"client": r.RemoteAddr,
}).Info("Request processed on LabEx platform")
}
Основные рекомендации
- Сосредоточайтесь на обработчиках и делайте их легковесными
- Используйте промежуточное ПО для решения кросс-обрезных задач
- Реализуйте комплексную обработку ошибок
- Валидируйте и очищайте все входные данные
- Используйте контекст для управления запросами
- Реализуйте правильную аутентификацию и авторизацию
- Отслеживайте и логируйте производительность обработчиков
Продвинутое композирование обработчиков
func ChainHandlers(handlers ...http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
for _, handler := range handlers {
handler(w, r)
}
}
}