httpx

package
v0.0.0-...-515b994 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2025 License: MIT Imports: 32 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	V *validator.Validate
)

Functions

func Accepted

func Accepted(w http.ResponseWriter, r *http.Request, data any)

Accepted - 202 ACCEPTED

Запрос принят на асинхронную обработку. Верните DTO со статусом или Job‑ID, по которому клиент сможет опросить результат.

Status: 202 Accepted

func BindValidate

func BindValidate[T any](r *http.Request, dst *T) (map[string]string, error)

BindValidate читает JSON‑тело, валидирует dst и локализует ошибки.

Возвращает:

  1. details - map[field]translated msg; nil, если валидация прошла или ошибка другого типа.
  2. err - любая ошибка процесса (декодинг, отсутствие валидатора, validator.ValidationErrors).

Использование:

var dto SignupDTO
if det, err := httpx.BindValidate(r, &dto); err != nil {
    if det != nil {
        httpx.ErrorValidation(w, r, det) // 400 + детали
    } else {
        httpx.ErrorBadRequest(w, r, err.Error())
    }
    return
}

func Created

func Created(w http.ResponseWriter, r *http.Request, location string, data any)

Created - 201 CREATED

Ресурс успешно создан. Передайте canonical‑URL в location (например, "/users/123"). Если location пустой - заголовок не ставится.

Status: 201 Created

func Error

func Error(w http.ResponseWriter, r *http.Request, status int, code, message string, details interface{})

Error формирует структурированный ответ с ошибкой (status 4xx, 5xx)

func ErrorBadGateway

func ErrorBadGateway(w http.ResponseWriter, r *http.Request, msg string)

ErrorBadGateway - 502 BAD_GATEWAY

Сервис-прокси получил ошибочный ответ **от вышестоящего бекенда**.

  • API-шлюз не смог достучаться до микросервиса или получил от него 500.
  • Ваш сервис сам является прокси к стороннему API.

Status: 502 Bad Gateway Code: BAD_GATEWAY

func ErrorBadRequest

func ErrorBadRequest(w http.ResponseWriter, r *http.Request, msg string)

ErrorBadRequest - 400 BAD_REQUEST Некорректный синтаксис или формат входящего запроса. Типовые случаи:

  • Клиент отправил повреждённый JSON / XML / form-body, который не парсится.
  • Слэш-значения query-параметров не приводятся к нужному типу (например, ?age=abc).
  • Отсутствует обязательный заголовок (Content-Type, Authorization и пр.).

Если структура распарсилась, но значения невалидны, используйте ErrorValidation. Рекомендуется писать понятный `msg`, чтобы UI/CLI показал человеку причину.

Status: 400 Bad Request

Code: BAD_REQUEST

func ErrorConflict

func ErrorConflict(w http.ResponseWriter, r *http.Request, msg string)

ErrorConflict - 409 CONFLICT

Конфликт состояния/уникальности.

  • Попытка создать ресурс с уже существующим уникальным полем (email).
  • PATCH версии объекта, который успел изменить другой пользователь (ETag).

Status: 409 Conflict

Code: CONFLICT

func ErrorExpectationFailed

func ErrorExpectationFailed(w http.ResponseWriter, r *http.Request, msg string)

ErrorExpectationFailed - 417 EXPECTATION_FAILED

Поле `Expect: 100-continue` или иное ожидание не было выполнено сервером.

Status: 417 Expectation Failed

Code: EXPECTATION_FAILED

func ErrorFailedDependency

func ErrorFailedDependency(w http.ResponseWriter, r *http.Request, msg string)

ErrorFailedDependency - 424 FAILED_DEPENDENCY

Предыдущая операция в той же цепочке (например, batch) завершилась неудачей.

Status: 424 Failed Dependency

Code: FAILED_DEPENDENCY

func ErrorForbidden

func ErrorForbidden(w http.ResponseWriter, r *http.Request, msg string)

ErrorForbidden - 403 FORBIDDEN

Клиент аутентифицирован, но не имеет доступа к ресурсу/действию.

  • Пользователь пытается изменить чужие данные.
  • Токен без нужного scope/role.

Отличается от 401 тем, что личность известна, но право запрещено.

Status: 403 Forbidden

Code: FORBIDDEN

func ErrorGone

func ErrorGone(w http.ResponseWriter, r *http.Request, res string)

ErrorGone - 410 GONE

Ресурс существовал, но удалён необратимо и не будет доступен снова. Пример: запись архивирована и политика запрещает её восстановление.

Status: 410 Gone

Code: GONE

func ErrorHTTPVersionNotSupported

func ErrorHTTPVersionNotSupported(w http.ResponseWriter, r *http.Request, msg string)

ErrorHTTPVersionNotSupported - 505 VERSION_NOT_SUPPORTED

Сервер не поддерживает версию протокола HTTP, указанную клиентом. В современных API встречается крайне редко.

Status: 505 HTTP Version Not Supported Code: VERSION_NOT_SUPPORTED

func ErrorHeaderFieldsTooLarge

func ErrorHeaderFieldsTooLarge(w http.ResponseWriter, r *http.Request, msg string)

ErrorHeaderFieldsTooLarge - 431 HEADER_FIELDS_TOO_LARGE

Совокупный размер заголовков превышает лимит сервера (cookies, tokens).

Status: 431 Request Header Fields Too Large

Code: HEADER_FIELDS_TOO_LARGE

func ErrorInsufficientStorage

func ErrorInsufficientStorage(w http.ResponseWriter, r *http.Request, msg string)

ErrorInsufficientStorage - 507 INSUFFICIENT_STORAGE

Сервер не смог завершить операцию из-за нехватки места (например, заключительный /upload-chunk превысил квоту диска).

  • Возвращайте в системах хранения, файловых сервисах, S3-совместимых API.

Status: 507 Insufficient Storage Code: INSUFFICIENT_STORAGE

func ErrorInternal

func ErrorInternal(w http.ResponseWriter, r *http.Request, msg string)

ErrorInternal - 500 INTERNAL

«Мы что-то сломали». Универсальная внутренняя ошибка, когда причина скрыта от клиента, а разработчики увидят её в логах.

  • Используйте при панике, ошибке базы, непредвиденном исключении.
  • Не выдавайте детали (stacktrace) публично - только лаконичное msg.

Status: 500 Internal Server Error Code: INTERNAL

func ErrorLegalReasons

func ErrorLegalReasons(w http.ResponseWriter, r *http.Request, msg string)

ErrorLegalReasons - 451 LEGAL_REASONS

Контент недоступен по юридическим причинам (DMCA, GDPR и т.д.). В `msg` желательно добавить ссылку на нормативный акт или запрос.

Status: 451 Unavailable For Legal Reasons

Code: LEGAL_REASONS

func ErrorLengthRequired

func ErrorLengthRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorLengthRequired - 411 LENGTH_REQUIRED

Отсутствует заголовок `Content-Length`, без которого сервер не желает принимать тело (например, для потоковой загрузки файлов).

Status: 411 Length Required

Code: LENGTH_REQUIRED

func ErrorLocked

func ErrorLocked(w http.ResponseWriter, r *http.Request, msg string)

ErrorLocked - 423 LOCKED

Ресурс заблокирован другим пользователем/процессом; операция невозможна, пока лок не будет снят.

Status: 423 Locked

Code: LOCKED

func ErrorLoopDetected

func ErrorLoopDetected(w http.ResponseWriter, r *http.Request, msg string)

ErrorLoopDetected - 508 LOOP_DETECTED

При обработке WebDAV-запроса обнаружена бесконечная рекурсия (циклическая ссылка). Остаётся ради стандарта; обычным REST-API не нужно.

Status: 508 Loop Detected Code: LOOP_DETECTED

func ErrorMethodNotAllowed

func ErrorMethodNotAllowed(w http.ResponseWriter, r *http.Request)

ErrorMethodNotAllowed - 405 METHOD_NOT_ALLOWED

Клиент использовал HTTP-метод, который не разрешён на данном URL. Например, попытка выполнить POST, когда разрешён только GET.

Status: 405 Method Not Allowed

Code: METHOD_NOT_ALLOWED

func ErrorMisdirectedRequest

func ErrorMisdirectedRequest(w http.ResponseWriter, r *http.Request, msg string)

ErrorMisdirectedRequest - 421 MISDIRECTED_REQUEST

Запрос адресован к серверу, который не может с ним справиться (обычно при использовании HTTP/2 + SNI не на тот хост).

Status: 421 Misdirected Request

Code: MISDIRECTED_REQUEST

func ErrorNetworkAuthRequired

func ErrorNetworkAuthRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorNetworkAuthRequired - 511 NETWORK_AUTH_REQUIRED

Клиент должен пройти сетевую аутентификацию (captive portal). Используется в публичных Wi-Fi до входа на портал.

Status: 511 Network Authentication Required Code: NETWORK_AUTH_REQUIRED

func ErrorNotAcceptable

func ErrorNotAcceptable(w http.ResponseWriter, r *http.Request, msg string)

ErrorNotAcceptable - 406 NOT_ACCEPTABLE

Сервер не может предоставить ответ в формате, указанном в заголовке Accept. Пример: клиент хочет `text/csv`, а сервис поддерживает только `application/json`.

Status: 406 Not Acceptable

Code: NOT_ACCEPTABLE

func ErrorNotExtended

func ErrorNotExtended(w http.ResponseWriter, r *http.Request, msg string)

ErrorNotExtended - 510 NOT_EXTENDED

Расширение протокола, необходимое клиенту, не поддерживается сервером. Определён в RFC 2774. На практике почти не встречается.

Status: 510 Not Extended Code: NOT_EXTENDED

func ErrorNotFound

func ErrorNotFound(w http.ResponseWriter, r *http.Request, res string)

ErrorNotFound - 404 NOT_FOUND

Запрошенный объект или эндпоинт отсутствует.

Передайте `res` («user», «file», «order») для генерации сообщения `user not found`; если пусто - вернётся универсальное «Resource not found».

Status: 404 Not Found

Code: NOT_FOUND

func ErrorNotImplemented

func ErrorNotImplemented(w http.ResponseWriter, r *http.Request, feature string)

ErrorNotImplemented - 501 NOT_IMPLEMENTED

Фича/эндпоинт задокументированы, но ещё не реализованы.

  • Полезно оставлять заглушки: фронт или интегратор поймут, что функционал появится позже, а не сломан.
  • Передайте `feature`, чтобы указать, что именно недоступно.

Status: 501 Not Implemented Code: NOT_IMPLEMENTED

func ErrorPayloadTooLarge

func ErrorPayloadTooLarge(w http.ResponseWriter, r *http.Request, msg string)

ErrorPayloadTooLarge - 413 PAYLOAD_TOO_LARGE

Тело запроса превышает установленный лимит (например, > 10 МБ). Укажите лимит в `msg`, чтобы пользователь мог исправиться.

Status: 413 Payload Too Large

Code: PAYLOAD_TOO_LARGE

func ErrorPaymentRequired

func ErrorPaymentRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorPaymentRequired - 402 PAYMENT_REQUIRED

Запрос отклонён из-за неоплаченного тарифа или превышения квоты.

Примеры применений:

  • SaaS-API блокирует вызовы, когда баланс 0 ₽.
  • Исчерпан месячный лимит сообщений / хранилища.

Status: 402 Payment Required

Code: PAYMENT_REQUIRED

func ErrorPreconditionFailed

func ErrorPreconditionFailed(w http.ResponseWriter, r *http.Request, msg string)

ErrorPreconditionFailed - 412 PRECONDITION_FAILED

Предусловия (`If-Match`, `If-None-Match`, ETag) не выполнены. Часто используется для оптимистических блокировок.

Status: 412 Precondition Failed

Code: PRECONDITION_FAILED

func ErrorPreconditionRequired

func ErrorPreconditionRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorPreconditionRequired - 428 PRECONDITION_REQUIRED

Сервер требует, чтобы запрос содержал `If-Match` / `If-Unmodified-Since` или подобные заголовки для безопасного изменения ресурса.

Status: 428 Precondition Required

Code: PRECONDITION_REQUIRED

func ErrorProxyAuthRequired

func ErrorProxyAuthRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorProxyAuthRequired - 407 PROXY_AUTH_REQUIRED

Используется прокси-серверами; приложение-бэкенд почти не применяет. Отправляйте, если ваш сервис сам является промежуточным прокси и требует авторизацию у клиента.

Status: 407 Proxy Authentication Required

Code: PROXY_AUTH_REQUIRED

func ErrorRangeNotSatisfiable

func ErrorRangeNotSatisfiable(w http.ResponseWriter, r *http.Request, msg string)

ErrorRangeNotSatisfiable - 416 RANGE_NOT_SATISFIABLE

Клиент запросил диапазон файла, выходящий за пределы размера ресурса.

Status: 416 Range Not Satisfiable

Code: RANGE_NOT_SATISFIABLE

func ErrorRequestTimeout

func ErrorRequestTimeout(w http.ResponseWriter, r *http.Request, msg string)

ErrorRequestTimeout - 408 REQUEST_TIMEOUT

Сервер закрыл соединение, потому что клиент слишком долго не присылал тело (обычно > дескриптора ReadTimeout). Эффективно предотвращает удержание соединений «зависшими» клиентами.

Status: 408 Request Timeout

Code: REQUEST_TIMEOUT

func ErrorServiceUnavailable

func ErrorServiceUnavailable(w http.ResponseWriter, r *http.Request, msg string)

ErrorServiceUnavailable - 503 SERVICE_UNAVAILABLE

Сервис временно недоступен: ведутся работы, перегрузка, отключён по feature-флагу или находится в процессе деплоя.

  • Верните заголовок `Retry-After`, если знаете время восстановления.
  • Отличается от 500 тем, что это **ожидаемое** состояние сервиса.

Status: 503 Service Unavailable Code: SERVICE_UNAVAILABLE

func ErrorTeapot

func ErrorTeapot(w http.ResponseWriter, r *http.Request)

ErrorTeapot - 418 TEAPOT

Пасхалка из протокола «Hyper Text Coffee Pot Control». Используется исключительно в демо/health-check’ах.

Status: 418 I'm a teapot

Code: TEAPOT

func ErrorTimeout

func ErrorTimeout(w http.ResponseWriter, r *http.Request, msg string)

ErrorTimeout - 504 TIMEOUT

**Шлюз** (reverse-proxy, API Gateway) не дождался ответа от внутреннего сервиса или стороннего API.

  • Укажите в `msg`, какой именно апстрим «завис», чтобы помочь Ops.
  • Клиентам можно советовать повторить запрос позднее.

Status: 504 Gateway Timeout Code: TIMEOUT

func ErrorTooEarly

func ErrorTooEarly(w http.ResponseWriter, r *http.Request, msg string)

ErrorTooEarly - 425 TOO_EARLY

Сервер отказывается обработать запрос, присланный слишком рано (0-RTT параметры небезопасны). Актуально только с TLS 1.3.

Status: 425 Too Early

Code: TOO_EARLY

func ErrorTooManyRequests

func ErrorTooManyRequests(w http.ResponseWriter, r *http.Request, msg string)

ErrorTooManyRequests - 429 RATE_LIMIT

Клиент превысил лимит запросов. Передавайте ретри-сообщение и (желательно) заголовок `Retry-After`.

Status: 429 Too Many Requests

Code: RATE_LIMIT

func ErrorURITooLong

func ErrorURITooLong(w http.ResponseWriter, r *http.Request, msg string)

ErrorURITooLong - 414 URI_TOO_LONG

URL + query-string столь велики, что сервер их не обрабатывает. Обычно случается при GET со сверхбольшими параметрами.

Status: 414 URI Too Long

Code: URI_TOO_LONG

func ErrorUnauthorized

func ErrorUnauthorized(w http.ResponseWriter, r *http.Request, msg string)

ErrorUnauthorized - 401 UNAUTHORIZED

К запросу не приложены корректные учётные данные:

  • Отсутствует или просрочен JWT / OAuth-токен.
  • Неверный Basic-auth логин/пароль.
  • В cookies нет сессионного идентификатора.

Не раскрывайте причину в деталях: злоумышленнику не нужно знать, просрочен ли токен или он просто неверен.

Status: 401 Unauthorized

Code: UNAUTHORIZED

func ErrorUnprocessableEntity

func ErrorUnprocessableEntity(w http.ResponseWriter, r *http.Request, msg string, det interface{})

ErrorUnprocessableEntity - 422 UNPROCESSABLE

Семантически неверный запрос: JSON корректен, но нарушает доменные правила. Укажите `det` (map / struct) с подробностями.

Status: 422 Unprocessable Entity

Code: UNPROCESSABLE

func ErrorUnsupportedMediaType

func ErrorUnsupportedMediaType(w http.ResponseWriter, r *http.Request, msg string)

ErrorUnsupportedMediaType - 415 UNSUPPORTED_MEDIA_TYPE

Тип содержимого запроса (`Content-Type`) не поддерживается сервером. Типичный пример: загрузили `application/xml`, а API ждёт `application/json`.

Status: 415 Unsupported Media Type

Code: UNSUPPORTED_MEDIA_TYPE

func ErrorUpgradeRequired

func ErrorUpgradeRequired(w http.ResponseWriter, r *http.Request, msg string)

ErrorUpgradeRequired - 426 UPGRADE_REQUIRED

Клиент должен перейти на другой протокол (чаще всего WebSocket).

Status: 426 Upgrade Required

Code: UPGRADE_REQUIRED

func ErrorValidation

func ErrorValidation(w http.ResponseWriter, r *http.Request, details interface{})

ErrorValidation - 400 VALIDATION

Структура запроса корректна, но значения нарушают бизнес-правила:

  • e-mail не соответствует RFC 5322; телефон вне E.164; age < 0 и т.п.
  • Отсутствуют взаимозависимые поля (например, одновременно latitude + longitude).

Передавайте `details` в формате `map[string]string`, где ключ - поле, значение - причина. Тогда фронтенд сможет подсветить ошибки конкретных полей.

Status: 400 Bad Request

Code: VALIDATION

func ErrorVariantAlsoNegotiates

func ErrorVariantAlsoNegotiates(w http.ResponseWriter, r *http.Request, msg string)

ErrorVariantAlsoNegotiates - 506 VARIANT_NEGOTIATES

Экзотика из RFC 2295 (Transparent Content Negotiation): круговая зависимость на этапе согласования варианта ресурса.

  • Практически не используется, но функция есть для полноты.

Status: 506 Variant Also Negotiates Code: VARIANT_NEGOTIATES

func JSON

func JSON(w http.ResponseWriter, r *http.Request, status int, data interface{})

JSON возвращает успешный ответ с заданным HTTP-статусом.

Пример:

httpx.JSON(w, r, http.StatusCreated, myObject)

func NoContent

func NoContent(w http.ResponseWriter, r *http.Request)

NoContent - 204 NO_CONTENT

Успешно, но тело не требуется (DELETE, PUT‑idempotent, healthz). Не возвращаем Envelope, чтобы не нарушать спецификацию.

Status: 204 No Content

func NonAuthoritative

func NonAuthoritative(w http.ResponseWriter, r *http.Request, data any)

NonAuthoritative - 203 NON_AUTHORITATIVE_INFORMATION

Содержимое получено из третьего источника (прокси, кеш). Используется редко.

Status: 203 Non‑Authoritative Information

func Ok

func Ok(w http.ResponseWriter, r *http.Request, data interface{})

Ok - 200 Ok

Универсальный шорткат для успешного ответа по умолчанию. Используйте, когда запрос выполнен успешно и сервер готов вернуть полезные данные (JSON) без каких‑либо побочных требований.

Типовые сценарии:

  • GET‑эндпойнт возвращает ресурс/список ресурсов;
  • PUT/PATCH успешно обновил объект и возвращает его актуальное состояние;
  • Health‑check, если хочется вернуть структурированное «status: ok».

Rекомендации:

  • В поле data передавайте DTO/структуру, пригодную для фронта;
  • Если ответ должен быть пустым → выберите NoContent(204), чтобы не посылать лишнее тело;

Status: 200 Ok Code:   - (успешным ответам machine‑code не требуется)

Пример:

article, _ := svc.Get(id)
httpx.Ok(w, r, article)

func PartialContent

func PartialContent(w http.ResponseWriter, r *http.Request, data any)

PartialContent - 206 PARTIAL_CONTENT

Ответ на запрос с Range‑заголовком (скачивание куска файла).

Status: 206 Partial Content

func RedirectFound

func RedirectFound(w http.ResponseWriter, r *http.Request, location string)

RedirectFound - 302 FOUND

Временный переезд (legacy). Современный эквивалент - 307. Используйте, если нужно сохранить метод GET / HEAD.

Status: 302 Found

func RedirectMovedPermanently

func RedirectMovedPermanently(w http.ResponseWriter, r *http.Request, location string)

RedirectMovedPermanently - 301 MOVED_PERMANENTLY

Канонический URL изменился навсегда (SEO‑friendly). Браузеры кешируют; поисковики передают “link‑juice”.

Status: 301 Moved Permanently

func RedirectMultipleChoices

func RedirectMultipleChoices(w http.ResponseWriter, r *http.Request, location string)

RedirectMultipleChoices - 300 MULTIPLE_CHOICES

Сервер предлагает несколько вариантов ресурса (например, разные форматы). Передайте URL контента по умолчанию в location, чтобы клиент мог автоматически перейти.

Status: 300 Multiple Choices

func RedirectNotModified

func RedirectNotModified(w http.ResponseWriter, r *http.Request)

RedirectNotModified - 304 NOT_MODIFIED

Особый случай: тело отсутствует; Location не нужен. Вызывайте, если ETag / If‑Modified‑Since совпали.

Status: 304 Not Modified

func RedirectPermanent

func RedirectPermanent(w http.ResponseWriter, r *http.Request, location string)

RedirectPermanent - 308 PERMANENT_REDIRECT

Постоянный переезд, но, как и 307, сохраняет метод + тело. Выбирайте для REST‑ресурсов, которые переместились навсегда.

Status: 308 Permanent Redirect

func RedirectSeeOther

func RedirectSeeOther(w http.ResponseWriter, r *http.Request, location string)

RedirectSeeOther - 303 SEE_OTHER

После успешного POST’а отправьте пользователя на GET‑страницу результата. Браузеры всегда выполнят последующий GET.

Status: 303 See Other

func RedirectTemporary

func RedirectTemporary(w http.ResponseWriter, r *http.Request, location string)

RedirectTemporary - 307 TEMPORARY_REDIRECT

Временный переезд: **сохраняет** HTTP‑метод и тело запроса (в отличие от 302). Подходит для API, когда POST нужно временно проксировать на другую ноду.

Status: 307 Temporary Redirect

func RegisterCustomValidator

func RegisterCustomValidator(tag string, fn validator.Func, messages map[string]string) error

RegisterCustomValidator добавляет кастомное правило в валидатор + переводы.

Пример:

httpx.RegisterCustomValidator("tz", validateTimeZone, map[string]string{
    "en": "Must be a valid IANA time zone",
    "ru": "Некорректная IANA таймзона (например, Europe/Moscow)",
})

func ResetContent

func ResetContent(w http.ResponseWriter, r *http.Request)

ResetContent - 205 RESET_CONTENT

Клиент должен сбросить форму/UI. Аналогично 204 - без тела.

Status: 205 Reset Content

func TranslatorFor

func TranslatorFor(r *http.Request) ut.Translator

TranslatorFor выбирает переводчик «на лету»

  1. X-Request-Lang
  2. Accept-Language
  3. fallback -> "en"

Types

type Envelope

type Envelope struct {
	Success bool        `json:"success"`            // true/false
	Data    any         `json:"data,omitempty"`     // полезная нагрузка (если success)
	Error   *ErrorBlock `json:"error,omitempty"`    // описание ошибки (если !success)
	TraceID string      `json:"trace_id,omitempty"` // X-Request-ID, сквозной идентификатор
}

Envelope - универсальный шаблон HTTP-ответа, как для успеха, так и для ошибки.

type ErrorBlock

type ErrorBlock struct {
	Code    string `json:"code"`              // код ошибки: VALIDATION, INTERNAL, etc
	Message string `json:"message"`           // человекочитаемое сообщение
	Details any    `json:"details,omitempty"` // map[string]string или любая структура
}

ErrorBlock - структура поля "error" в теле ответа.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL