Files
httputil/README.md

60 lines
1.4 KiB
Markdown
Raw Normal View History

# httputil
Typed HTTP handler adapters and response helpers for stdlib `net/http`.
## Install
```
go get code.nochebuena.dev/go/httputil
```
## Typed handlers
```go
// JSON body + validation + typed response
r.Post("/orders", httputil.Handle(validator, svc.CreateOrder))
// No request body (GET / DELETE)
r.Get("/orders/{id}", httputil.HandleNoBody(svc.GetOrder))
// Request body, no response body (204)
r.Delete("/orders/{id}", httputil.HandleEmpty(validator, svc.DeleteOrder))
// Manual handler with centralised error mapping
r.Get("/raw", httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
data, err := svc.Load(r.Context(), chi.URLParam(r, "id"))
if err != nil {
return err
}
return httputil.JSON(w, http.StatusOK, data)
}))
```
## Error mapping
`xerrors.Code` → HTTP status:
| Code | Status |
|---|---|
| `ErrInvalidInput` | 400 |
| `ErrUnauthorized` | 401 |
| `ErrPermissionDenied` | 403 |
| `ErrNotFound` | 404 |
| `ErrAlreadyExists` | 409 |
| `ErrInternal` | 500 |
| `ErrNotImplemented` | 501 |
| `ErrUnavailable` | 503 |
| `ErrDeadlineExceeded` | 504 |
| unknown | 500 |
Error response body:
```json
{"code": "NOT_FOUND", "message": "record not found"}
```
Fields from `xerrors.Err` are merged into the top-level response object.
## Dependencies
- `code.nochebuena.dev/go/xerrors`
- `code.nochebuena.dev/go/valid`