web

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package web is the Laravel-style HTTP framework for lagodev.

Bu paket Gin/Fiber'ga muqobil sodda, framework-mustaqil API beradi. Asosiy tushunchalar:

  • web.App — ilovaning tepa darajadagi konteyner (Router + Server + DB)
  • web.Context — har bir so'rovga moslangan helper'lar (JSON, Bind, Param)
  • web.Router — Laravel-uslubidagi marshrutlash (Get/Post/Resource/Group)
  • web.ResourceController — RESTful 5 metodli interfeys

Minimal misol:

app := web.New()
app.Get("/", func(c *web.Context) { c.String(200, "hi") })
app.Resource("posts", &PostController{})
app.Run(":8080")

Index

Constants

View Source
const DefaultBodyLimit int64 = 1 << 20 // 1 MiB

DefaultBodyLimit caps c.Bind() reads when no BodyLimit() middleware is configured. Override per app by chaining BodyLimit(n) on the router.

Variables

This section is empty.

Functions

func Validate added in v0.13.0

func Validate(dst any) error

Validate runs lightweight rules against struct tags on dst. Supported tag form:

`validate:"required,min=3,max=200,email,oneof=admin user"`

Supported rules:

required             — disallow zero values (including empty strings)
min=N                — int/float ≥ N, string length ≥ N, slice len ≥ N
max=N                — opposite of min
gt=N                 — strictly greater than N (int/float/string-len)
lt=N                 — strictly less than N
email                — basic RFC-ish email shape
url                  — must start with http:// or https://
oneof=a b c          — value must equal one of the listed tokens
alpha                — letters only
alphanumeric         — letters and digits only
uuid                 — 8-4-4-4-12 hex pattern
numeric              — string must parse as a number (int or float)
integer              — string must parse as an integer
ip                   — string must be a valid IPv4 or IPv6 address

On failure Validate returns *ValidationError; respond() maps it to a 422 Unprocessable Entity with `{"errors": {...}}`.

Types

type App

type App struct {
	*Router // Top-level marshrutlash uchun embedded
	// contains filtered or unexported fields
}

App — ilovaning tepa darajadagi konteyner. Marshrutlar, ulanish, sozlamalar va HTTP server'ni birgalikda saqlaydi. Foydalanuvchi faqat main.go'da `web.New(...).Run()` chaqiradi.

func New

func New(opts ...Option) *App

New — yangi App yaratadi va kerakli o'rta dasturlarni standart qilib qo'shadi (Logger + Recovery). Disable qilish uchun Reset() chaqiring.

func (*App) DB

func (a *App) DB() *database.Connection

DB — biriktirilgan database.Connection'ni qaytaradi (yo'q bo'lsa nil).

func (*App) Health added in v0.19.0

func (a *App) Health()

Health registers a liveness endpoint at `/healthz` that always returns 200 once the app is up. Kubernetes uses this to decide whether to restart the pod.

func (*App) MustRun

func (a *App) MustRun(addr ...string)

MustRun — Run() qaytargan xato bo'lsa fatal log bilan to'xtaydi. Asosiy main() uchun qulay.

func (*App) Ready added in v0.19.0

func (a *App) Ready(checks ...HealthCheck)

Ready registers a readiness endpoint at `/readyz` that runs every supplied probe in parallel. If any probe returns an error the endpoint replies with 503 + the name of the first failing check; otherwise 200. Kubernetes uses this to decide whether to route traffic to the pod.

`Ready` is additive — call it once, listing every probe the app needs.

func (*App) Run

func (a *App) Run(addr ...string) error

Run — HTTP serverni ishga tushiradi va Ctrl+C kelguncha bloklanadi. Graceful shutdown signali kelganda joriy so'rovlar tamomlanguncha kutadi.

func (*App) Test added in v0.19.0

func (a *App) Test(req *http.Request) *httptest.ResponseRecorder

Test drives a single request through the App's middleware chain and route table without binding a port. Returns the httptest.ResponseRecorder so tests can assert on Code, Body, and headers.

rec := app.Test(httptest.NewRequest("GET", "/users/42", nil))
if rec.Code != 200 { t.Fatal(...) }

The app does NOT need to be Run() — Test materialises the route table on demand. Safe to call concurrently with other Test() invocations, but not with a live Run().

type CORSConfig added in v0.13.0

type CORSConfig struct {
	AllowedOrigins   []string
	AllowedMethods   []string
	AllowedHeaders   []string
	ExposedHeaders   []string
	AllowCredentials bool
	MaxAgeSeconds    int
}

CORSConfig kengaytirilgan CORS sozlamalari.

type CSRFConfig added in v0.13.0

type CSRFConfig struct {
	// CookieName for the CSRF token cookie. Default "csrf_token".
	CookieName string
	// HeaderName clients send the token in. Default "X-CSRF-Token".
	HeaderName string
	// FormField fallback name for form posts. Default "_csrf".
	FormField string
	// Secure marks the cookie HTTPS-only. Default true.
	Secure bool
	// SameSite for the cookie. Default http.SameSiteLaxMode.
	SameSite http.SameSite
	// MaxAge of the cookie in seconds. Default 7200 (2h).
	MaxAge int
}

CSRFConfig customises CSRF behaviour.

type Context

type Context struct {
	// Writer — yozish uchun standart http.ResponseWriter.
	Writer http.ResponseWriter
	// Request — kelgan HTTP so'rov.
	Request *http.Request
	// DB — agar App.WithDatabase orqali biriktirilgan bo'lsa, ulanish.
	// Hech qachon nil bo'lmasligi shart emas; nil bo'lganda foydalanuvchi
	// o'zi tekshiradi.
	DB *database.Connection
	// contains filtered or unexported fields
}

Context bitta HTTP so'rovni ifoda etadi. U handler'lar va middleware'lar orasidan o'tadi va so'rov/javob ustida ishlash uchun helper'lar beradi.

func (*Context) Attachment added in v0.19.0

func (c *Context) Attachment(path, filename string)

Attachment serves a file with `Content-Disposition: attachment` so the browser triggers a download. `filename` is the suggested filename shown to the user.

func (*Context) BadRequest

func (c *Context) BadRequest(msg string)

BadRequest 400 + JSON xato.

func (*Context) Bind

func (c *Context) Bind(dst any) error

Bind so'rov body'sini JSON sifatida dst'ga decode qiladi. Xato bo'lsa avtomatik 400 Bad Request qaytaradi va sentinel xatoni qaytaradi.

Body BodyLimit() middleware tomonidan cheklangan bo'lmasa, default 1 MiB chegara qo'llaniladi (DoS oldini olish).

func (*Context) BindAndValidate added in v0.13.0

func (c *Context) BindAndValidate(dst any) error

BindAndValidate so'rov body'sini Bind qiladi va keyin Validate() ishga tushiradi. Validatsiya muvaffaqiyatsiz bo'lsa, qaytarilgan xato *ValidationError bo'ladi va respond() uni 422 ga aylantiradi:

{"errors": {"field": "message"}}

func (*Context) ClearCookie added in v0.13.0

func (c *Context) ClearCookie(name string, opts ...CookieOption)

ClearCookie expires the named cookie immediately.

func (*Context) Cookie added in v0.13.0

func (c *Context) Cookie(name string) string

Cookie returns the value of the named cookie, or "" if missing.

func (*Context) Created added in v0.8.0

func (c *Context) Created(v any) any

Created — Store handler uchun qulay yordamchi. 201 statusi'ni belgilab foydalanuvchi return value, nil yozsa, framework JSON'ga aylantiradi:

return ctx.Created(post), nil

Eslatma: Status'ni darhol writer'ga yozmaydi — respond() body yozish chog'ida 201 ni qo'llaydi, shu sababli Content-Type to'g'ri belgilanadi.

func (*Context) Ctx

func (c *Context) Ctx() context.Context

Ctx so'rovning context.Context'ini qaytaradi. DB chaqiruvlariga uzating:

user, err := orm.Query[User](c.DB).Find(c.Ctx(), id)

func (*Context) Error

func (c *Context) Error(err error) bool

Error err nil emas bo'lsa, mos status kodi bilan JSON javob qaytaradi:

  • *ValidationError → 422 Unprocessable Entity
  • orm.ErrNotFound → 404 Not Found
  • boshqa → 500 Internal Server Error

Foydalanish:

if c.Error(err) { return }

func (*Context) File added in v0.19.0

func (c *Context) File(path string)

File serves a file from disk with `Content-Disposition: inline`. The browser shows the file (PDF preview, image render, …) instead of downloading it.

Path is passed verbatim to http.ServeFile — apply filepath.Clean and your own sandboxing if the path is derived from user input.

func (*Context) Forbidden

func (c *Context) Forbidden(msg string)

Forbidden 403 + JSON xato.

func (*Context) Get

func (c *Context) Get(key string) (any, bool)

Get saqlangan qiymatni oladi.

func (*Context) InternalError

func (c *Context) InternalError(err error)

InternalError 500 + JSON xato. Production'da (APP_ENV=production) generic "internal server error" javobi yuboriladi — raw error matnida stack/DB ma'lumotlari sizib ketmasin. Boshqa muhitlarda to'liq matn ko'rsatiladi (development ergonomikasi).

func (*Context) JSON

func (c *Context) JSON(code int, v any)

JSON v'ni JSON sifatida code statusi bilan yuboradi.

func (*Context) MustBind

func (c *Context) MustBind(dst any) bool

MustBind Bind bilan bir xil lekin xato bo'lsa true qaytaradi. Foydalanish: if !c.MustBind(&payload) { return }

func (*Context) NoContent

func (c *Context) NoContent()

NoContent 204 javobi (body yo'q).

func (*Context) NotFound

func (c *Context) NotFound(msg string)

NotFound 404 + JSON xato.

func (*Context) Param

func (c *Context) Param(name string) string

Param yo'l parametri qiymatini qaytaradi (masalan "/posts/{id}" → "id"). Yo'qol bo'lsa, bo'sh qator.

func (*Context) ParamInt

func (c *Context) ParamInt(name string) int

ParamInt yo'l parametri'ni int qiymat sifatida qaytaradi.

func (*Context) ParamUint

func (c *Context) ParamUint(name string) uint64

ParamUint yo'l parametri'ni uint64 ko'rinishida qaytaradi. Xato yoki bo'sh bo'lsa 0 qaytadi.

func (*Context) Query

func (c *Context) Query(name string) string

Query URL-dan so'rov stringini oladi (?key=value).

func (*Context) QueryDefault

func (c *Context) QueryDefault(name, fallback string) string

QueryDefault Query bilan bir xil, lekin bo'sh bo'lsa fallback qaytaradi.

func (*Context) QueryInt

func (c *Context) QueryInt(name string, fallback int) int

QueryInt URL parametrini int sifatida o'qiydi. Xato bo'lsa fallback.

func (*Context) Redirect added in v0.19.0

func (c *Context) Redirect(code int, url string)

Redirect sends an HTTP redirect response (`Location` header + the given status code). Use 301/302/307/308 as appropriate. Marks the response body as written so respond() does not append a JSON tail.

func (*Context) SSE added in v0.19.0

func (c *Context) SSE(event, data string) error

SSE writes a single Server-Sent Events frame to the client. The first call to SSE sets `Content-Type: text/event-stream` and the other SSE-specific headers; subsequent calls just append more events. The connection stays open until the handler returns or the client disconnects.

Usage:

for evt := range source {
    if err := c.SSE("message", evt.JSON()); err != nil { return nil, err }
    select {
    case <-c.Ctx().Done(): return nil, nil
    default:
    }
}

func (*Context) Set

func (c *Context) Set(key string, value any)

Set context ichida key/value saqlaydi (masalan, authenticated user).

func (*Context) SetCookie added in v0.13.0

func (c *Context) SetCookie(name, value string, opts ...CookieOption)

SetCookie writes a cookie with Laravel-grade safe defaults:

Path     = "/"
HttpOnly = true   (use CookieReadable() to expose to JS)
Secure   = true   (use CookieInsecure() in local HTTP dev)
SameSite = Lax    (use CookieSameSite() to override)

func (*Context) Status

func (c *Context) Status(code int)

Status faqat status kodini yozadi, body yubormaydi.

func (*Context) Stream added in v0.19.0

func (c *Context) Stream(code int, contentType string, r io.Reader) (int64, error)

Stream sends Content-Type and copies from r into the response body, flushing periodically if the underlying ResponseWriter is a http.Flusher. Use for streaming uploads (CSV exports, large JSON arrays produced incrementally, …) without buffering everything in memory.

Stream sets the response status to `code` and writes the headers before the first byte of the body. Returns the number of bytes copied and any read/write error.

func (*Context) String

func (c *Context) String(code int, body string)

String matn javobi.

func (*Context) Unauthorized

func (c *Context) Unauthorized(msg string)

Unauthorized 401 + JSON xato.

func (*Context) UnprocessableEntity added in v0.13.0

func (c *Context) UnprocessableEntity(ve *ValidationError)

UnprocessableEntity 422 + ValidationError'ning fields'ini JSON sifatida yuboradi.

func (*Context) WithStatus added in v0.13.0

func (c *Context) WithStatus(code int) *Context

WithStatus — keyingi body yozilganda foydalaniladigan status kodi. Status() bilan farqi: Status() darhol WriteHeader chaqiradi, bu esa faqat kelajakdagi JSON/String chaqiruvi uchun rejalashtiradi.

type CookieOption added in v0.13.0

type CookieOption func(*http.Cookie)

CookieOption customises a cookie set via c.SetCookie.

func CookieDomain added in v0.13.0

func CookieDomain(d string) CookieOption

CookieDomain restricts the cookie to a domain.

func CookieExpires added in v0.13.0

func CookieExpires(t time.Time) CookieOption

CookieExpires sets the Expires attribute. Prefer CookieMaxAge.

func CookieInsecure added in v0.13.0

func CookieInsecure() CookieOption

CookieInsecure marks the cookie as **not** Secure. Use only for local HTTP development. The default is Secure=true.

func CookieMaxAge added in v0.13.0

func CookieMaxAge(seconds int) CookieOption

CookieMaxAge sets the Max-Age in seconds (0 means session cookie).

func CookiePath added in v0.13.0

func CookiePath(p string) CookieOption

CookiePath overrides the cookie Path (default "/").

func CookieReadable added in v0.13.0

func CookieReadable() CookieOption

CookieReadable marks the cookie as readable by JavaScript (turns off HttpOnly). Use only when the client must echo the value into a header — e.g. CSRF double-submit tokens.

func CookieSameSite added in v0.13.0

func CookieSameSite(s http.SameSite) CookieOption

CookieSameSite overrides the SameSite attribute (default Lax).

type Handler

type Handler func(c *Context) (any, error)

Handler — har bir route metodining imzosi.

Laravel uslubida ikki qiymat qaytaradi:

  • any — JSON sifatida javob beriladi (nil bo'lsa, 204 No Content)
  • error — nil emas bo'lsa, avtomat xato javobi (orm.ErrNotFound → 404, qolganlari → 500). c.Status(N) chaqirib ham qo'shimcha holat kodini majburlash mumkin.

type HealthCheck added in v0.19.0

type HealthCheck struct {
	Name  string
	Probe func(ctx context.Context) error
	// Timeout caps the probe; default 2 seconds.
	Timeout time.Duration
}

HealthCheck is a probe function used by Ready(). It must return quickly — Kubernetes typically calls /readyz every 5–10 seconds.

app.Ready(
    web.HealthCheck{Name: "db", Probe: func(ctx context.Context) error {
        return conn.DB.PingContext(ctx)
    }},
)

type Middleware

type Middleware func(next Handler) Handler

Middleware — Handler'ni boshqa Handler bilan o'rab oladigan funksiya. Birinchi ro'yxatga olingan middleware tashqaridagisi (so'rov birinchi uning ichidan o'tadi).

func Auth

func Auth() Middleware

Auth — sodda Bearer-token middleware. Faqat sarlavha mavjudligini tekshiradi va xom token'ni context'ga yozadi. Token'ni tekshirish kerak bo'lsa AuthJWT(manager) ishlating.

func AuthJWT added in v0.9.0

func AuthJWT(m *auth.Manager) Middleware

AuthJWT — JWT'ni tekshiradigan to'liq middleware. Token noto'g'ri yoki muddati o'tgan bo'lsa 401 qaytaradi. Muvaffaqiyat holida claims context'ga yoziladi: "auth_user_id", "auth_role", "auth_claims".

func BodyLimit added in v0.13.0

func BodyLimit(n int64) Middleware

BodyLimit caps the size of the request body to n bytes. Bodies larger than n cause subsequent reads (including c.Bind) to fail with `http: request body too large`. Apply globally to prevent DoS.

func CORS

func CORS(allowedOrigins ...string) Middleware

CORS — sodda CORS middleware. Origin'ni allowedOrigins ro'yxati bilan taqqoslaydi (yoki "*" — har qanday). Kuchaytirilgan default'lar bilan:

  • Faqat ruxsat etilgan origin'ga "Access-Control-Allow-Origin" sarlavhasi yuboriladi (boshqa origin'ga umuman jo'natilmaydi).
  • Preflight uchun Access-Control-Request-Headers aks sado beriladi.
  • "*" + credentials kombinatsiyasi taqiqlangan (brauzer ham qabul qilmaydi; framework bu xavfsiz emas konfiguratsiyani yubormaydi).
  • Preflight javoblarini brauzer 10 minut cache qiladi.

Credentials (cookie/Authorization) ruxsat berish uchun CORSConfig orqali AllowCredentials = true sozlang va wildcard ishlatmang.

func CORSWithConfig added in v0.13.0

func CORSWithConfig(cfg CORSConfig) Middleware

CORSWithConfig — CORSConfig'dan middleware quradi.

func CSRF added in v0.13.0

func CSRF(cfg ...CSRFConfig) Middleware

CSRF implements double-submit-cookie CSRF protection. On safe methods (GET/HEAD/OPTIONS) it issues a token cookie if missing. On unsafe methods (POST/PUT/PATCH/DELETE) it requires the same token in the header (or form field for HTML forms) and rejects with 403 on mismatch. Constant-time comparison prevents timing leaks.

Pass a zero CSRFConfig for safe defaults.

func Logger

func Logger(l *log.Logger) Middleware

Logger — request access logger. Writes one line per request with method, path, status, latency, client IP, response size (bytes written), and (if RequestID middleware ran before it) the request id. App.New() applies this automatically.

Format: `METHOD PATH STATUS DURATION ip=IP size=BYTES req=ID`.

func RateLimit added in v0.13.0

func RateLimit(limit int, window time.Duration) Middleware

RateLimit applies a fixed-window per-IP rate limit. Up to `limit` requests are allowed per `window`; further requests get 429 with a `Retry-After` header.

The store is in-process — suitable for a single replica. Behind a load balancer, replace with a Redis-backed limiter (see TODO).

func Recovery

func Recovery(l *log.Logger) Middleware

Recovery — catches handler panics, logs the recovered value + stack trace to l, and returns a generic 500 JSON response. The recovered value is **never** sent to the client (it would otherwise leak secrets like "panic: db password: hunter2"). App.New() applies this automatically.

func RequestID added in v0.13.0

func RequestID() Middleware

RequestID ensures every request has an X-Request-ID. If the client supplied one, it is echoed (truncated to 128 chars). Otherwise a 16- byte random hex is generated. The ID is stored in the context under "request_id" and mirrored to the response header for log correlation.

func SecurityHeaders added in v0.13.0

func SecurityHeaders(cfg ...SecurityHeadersConfig) Middleware

SecurityHeaders attaches a conservative set of browser security headers to every response. Call without arguments for safe defaults.

func Throttle added in v0.13.0

func Throttle(limit int, window time.Duration) Middleware

Throttle is an alias for RateLimit using Laravel naming.

type Option

type Option func(*App)

Option — funksional sozlash usuli.

func WithAddr

func WithAddr(addr string) Option

WithAddr — server tinglovchi manzili (default ":8080").

func WithDatabase

func WithDatabase(conn *database.Connection) Option

WithDatabase — ochiq *database.Connection'ni ilovaga biriktiradi. Handler'lardan `c.DB` orqali foydalanish mumkin.

func WithManager

func WithManager(mgr *database.Manager) Option

WithManager — *database.Manager'ni biriktiradi. Run() chiqqach Close() chaqiriladi.

func WithMigrations

func WithMigrations(reg *migrations.Registry) Option

WithMigrations — Run() vaqtida migratsiyalarni avtomat qo'llashni yoqadi. Registry nil bo'lsa, package-default ishlatiladi.

func WithShutdownTimeout

func WithShutdownTimeout(d time.Duration) Option

WithShutdownTimeout — graceful shutdown vaqti (default 10s).

type ResourceController

type ResourceController interface {
	Index(c *Context) (any, error)
	Show(c *Context) (any, error)
	Store(c *Context) (any, error)
	Update(c *Context) (any, error)
	Destroy(c *Context) (any, error)
}

ResourceController — Resource() bilan ishlatish uchun interfeys. 5 ta RESTful metod (any, error) qaytaradi — Laravel uslubida.

type Route

type Route struct {
	Method  string
	Path    string
	Handler Handler
}

Route — bitta ro'yxatdan o'tgan marshrut.

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router — marshrut, group va middleware'larni e'lon qilish vositasi.

func (*Router) APIResource

func (r *Router) APIResource(name string, ctrl ResourceController)

APIResource — Resource bilan bir xil; nom Laravel konventsiyasi uchun.

func (*Router) Any

func (r *Router) Any(path string, h Handler)

Any — barcha standart HTTP fe'llari uchun bir xil handler.

func (*Router) Delete

func (r *Router) Delete(path string, h Handler)

func (*Router) Get

func (r *Router) Get(path string, h Handler)

HTTP verb shortcutlar — har biri prefiks va middleware bilan to'liq route ro'yxatga oladi.

func (*Router) Group

func (r *Router) Group(prefix string, fn func(g *Router))

Group — yangi prefiks va o'rta dasturlar to'plamiga ega bola router. Misol: app.Group("/api/v1", func(g *web.Router) { g.Resource("posts", ...) })

func (*Router) Head

func (r *Router) Head(path string, h Handler)

func (*Router) Options

func (r *Router) Options(path string, h Handler)

func (*Router) Patch

func (r *Router) Patch(path string, h Handler)

func (*Router) Post

func (r *Router) Post(path string, h Handler)

func (*Router) Put

func (r *Router) Put(path string, h Handler)

func (*Router) Resource

func (r *Router) Resource(name string, ctrl ResourceController)

Resource — RESTful 5 ta marshrutni avtomat e'lon qiladi.

GET    /posts            → Index
GET    /posts/{id}       → Show
POST   /posts            → Store
PUT    /posts/{id}       → Update
PATCH  /posts/{id}       → Update
DELETE /posts/{id}       → Destroy

`name` — ko'plik (`posts`, `users`).

func (*Router) Routes

func (r *Router) Routes() []Route

Routes — barcha ro'yxatga olingan marshrutlarning snapshot'i.

func (*Router) Use

func (r *Router) Use(mw ...Middleware)

Use — har bir keyingi marshrutga qo'llaniladigan middleware.

type SecurityHeadersConfig added in v0.13.0

type SecurityHeadersConfig struct {
	// ContentSecurityPolicy sent as Content-Security-Policy. Empty omits the header.
	ContentSecurityPolicy string
	// FrameOptions for X-Frame-Options. Empty omits the header.
	FrameOptions string
	// ReferrerPolicy for Referrer-Policy. Empty omits the header.
	ReferrerPolicy string
	// PermissionsPolicy for Permissions-Policy. Empty omits the header.
	PermissionsPolicy string
	// HSTS sets Strict-Transport-Security. Empty omits the header.
	// Set only when serving over HTTPS — otherwise clients lock onto a
	// broken scheme.
	HSTS string
	// NoSniff toggles X-Content-Type-Options: nosniff (default true).
	NoSniff bool
}

SecurityHeadersConfig controls SecurityHeaders middleware output.

Zero value gives Laravel-grade safe defaults. Override per field to loosen — never to silently disable everything.

type ValidationError added in v0.13.0

type ValidationError struct {
	Message string
	Fields  map[string]string
}

ValidationError is the error type respond() recognises and maps to HTTP 422 Unprocessable Entity. Fields is keyed by JSON field name (or struct field name when no `json:"..."` tag is present); each value is a human-readable message.

func (*ValidationError) Error added in v0.13.0

func (e *ValidationError) Error() string

Error implements the error interface.

Jump to

Keyboard shortcuts

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