Volga
Home
Agent Skill
API Docs
GitHub
  • English
  • Русский
Home
Agent Skill
API Docs
GitHub
  • English
  • Русский
  • Home
  • Getting Started

    • Quick Start
    • Handlers
    • Route Parameters
    • Query Parameters
    • Route Groups
  • Requests & Responses

    • Headers
    • Handling JSON
    • Handling Form Data
    • Working with Files
    • Multipart Responses
    • Raw Request Body
    • Cookies
    • Validating Requests
  • Middleware & Infrastructure

    • Basic Middleware
    • Custom Middleware
    • Parameterized Middleware
    • Response Compression
    • Request Decompression
    • CORS (Cross-Origin Resource Sharing)
    • Static Files
    • Rate Limiting
    • Configuration Files
    • OpenAPI
  • Security & Access

    • Authentication and Authorization
    • OAuth 2.1 & OpenID Connect
    • OAuth 2.1 Client
    • Machine-to-Machine Grants
    • DPoP — Sender-Constrained Tokens
  • Reliability & Observability

    • Global Error Handling
    • Tracing & Logging
    • Request cancellation
    • Graceful Shutdown
  • Protocols & Realtime

    • HTTP Versions and Methods
    • HTTPS
    • WebSockets
    • Server-Sent Events (SSE)
  • Advanced Patterns

    • Dependency Injection
    • Custom Handling of HEAD, OPTIONS, and TRACE Methods
  • Agent Skill

HTTP Versions and Methods

HTTP/1 and HTTP/2

Starting with v0.3.1, you can configure the HTTP version. If you add Volga like this, HTTP/1 is used by default:

[dependencies]
volga = { version = "..." }

To enable HTTP/2, add the http2 feature or use full:

[dependencies]
volga = { version = "...", features = ["full"] }

With full, HTTP/2 is used when possible, and it falls back to HTTP/1 automatically.

HTTP Methods

Volga has a named map_* method for every standard verb, registered on an App or on a RouteGroup:

app.map_get("/items", || async { ok!("list") });
app.map_post("/items", || async { ok!("created") });
app.map_put("/items/{id}", || async { ok!("updated") });
app.map_patch("/items/{id}", || async { ok!("patched") });
app.map_delete("/items/{id}", || async { ok!("deleted") });
app.map_head("/items", || async { ok!() });
app.map_options("/items", || async { ok!() });
app.map_trace("/items", || async { ok!() });

Tips

A HEAD request with no route of its own is answered by the GET route for the same path, through that route's middleware and CORS policy, so you only need map_head for a custom implementation. See Custom Handling of HEAD, OPTIONS, and TRACE.

The QUERY method

Starting with v0.9.4, Volga supports the HTTP QUERY method — a safe, idempotent verb that carries a request body, for searches too large or too structured to express in a URI query string.

Register a handler with map_query():

use volga::{App, Json, ok};
use serde::Deserialize;

#[derive(Deserialize)]
struct SearchQuery {
    criteria: String
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new();

    app.map_query("/search", |query: Json<SearchQuery>| async move {
        // run the search by query.criteria...
        ok!("search results...")
    });

    app.run().await
}

Test it with curl:

> curl -X QUERY "http://localhost:7878/search" -H "Content-Type: application/json" -d '{"criteria":"volga"}'

Warning

Don't confuse map_query() with the Query<T> extractor: the former registers a route for the QUERY verb, the latter reads the URI query string of any request.

Tips

Prefer putting complex selection criteria in the request body of a QUERY request. Use URI query parameters only for routing or cache-affecting metadata — tenant, locale, version, flags, pagination compatibility.

Any method

Also since v0.9.4, map() registers a route for any HTTP method. It is useful when the verb is only known at runtime, when the same handler serves several methods, or for non-standard verbs:

use volga::{App, ok};
use volga::http::Method;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new();

    app.map(Method::GET, "/hello", || async {
        ok!("Hello, World!")
    });

    // a string verb and a runtime-built pattern work as well
    app.map("QUERY", format!("/search/{}", "v1"), || async {
        ok!("search results...")
    });

    app.run().await
}

The method argument accepts anything that converts into a Method — including string verbs — and the pattern accepts both a borrowed &str (no allocation) and an owned String built at runtime.

Warning

map() panics if the method cannot be converted into a valid Method. Routes are registered at startup, so an invalid verb is a programming error rather than a runtime condition.

Last Updated: 9/14/26, 6:45 AM
Next
HTTPS