Gotham Web Framework

repository·main·Indexed 25 days ago

https://github.com/gotham-rs/gotham

A high-performance, asynchronous web framework for Rust version 0.8.1 built on the Tokio runtime and Hyper HTTP implementation. Gotham prioritizes stability, type safety, and security, providing tools for asynchronous request handlers, stateful handlers, and middleware. It includes support for Diesel database integration, cookie management, HTML form parsing (urlencoded and multipart), and finalizers for executing logic before responses are returned.

Tokens
26.8K
Snippets
66
Records
153
Agent score
80%

What's inside gotham

  1. Overview of the Gotham web framework

    main

    Gotham is a flexible Rust web framework designed for stability, safety, security, and speed. It is built on top of the Tokio runtime and Hyper, providing an asynchronous-first experience.

    Key Features

    • Stability Focused: All releases target stable Rust. Automated builds are also run against Rust beta and nightly to ensure future compatibility.
    • Statically Typed: Leverages Rust's type system to ensure applications are correctly expressed at compile time.
    • Async Everything: Built on Tokio and Hyper, making all framework types asynchronous by default.
    • High Performance: Optimized for low latency, with request processing times measurable in microseconds (µs).
  2. What is a Gotham Handler?

    main

    A Handler is the primary building block of a Gotham web framework application. It is an asynchronous function that takes a State value (representing the request and related runtime state) and resolves to an HTTP response.

    In a typical workflow, developers create handlers and use the Router to map them to specific routes. When an incoming request matches a route, the Router invokes the associated Handler to process it.

  3. What is BorrowBag?

    main
    BorrowBag is a type-safe, heterogeneous collection designed for zero-cost addition and borrowing. It allows you to store values of any type within a single collection. When you add a value, it returns a Handle that can be used to borrow that specific value back later. Because the collection is add-only, the Handle remains valid for the entire lifetime of the BorrowBag.
  4. Understand Middleware and Pipelines in Gotham

    main
    Gotham uses Middleware and Pipelines to process web requests. This example demonstrates how to implement middleware using async/await syntax, allowing for non-blocking operations within the request/response lifecycle. Middleware can intercept requests, modify them, or perform side effects (like logging or header injection) before they reach the final handler, and can also process responses on their way back to the client.
  5. Use multiple middleware pipelines for different routes

    main

    Gotham allows you to define different middleware pipelines for different sets of routes. This enables you to apply specific logic (like session management, cookie setting, or content-type negotiation) only to the routes that require them, while keeping other routes lightweight.

    In this pattern:

    • Global/Default routes: Can run with a minimal pipeline (e.g., only request ID tracking).
    • Session-protected routes: Can include session middleware that sets cookies (e.g., /account).
    • Admin routes: Can stack multiple middleware layers, such as a default pipeline plus an additional admin-specific session middleware (e.g., /admin).
    • API routes: Can include middleware for content negotiation, such as enforcing specific Accept headers and returning JSON while rejecting unsupported types like XML (e.g., /api).
  6. Route using Scopes in Gotham

    main

    In Gotham, you can organize and combine multiple Routes under a common path prefix using Scopes. This allows for logical grouping of related endpoints (e.g., grouping all /checkout related routes under a single scope) and helps maintain a clean routing hierarchy in complex applications.

    To use scopes, you define a scope at a specific path and then attach routes or sub-scopes within it. This example demonstrates how to structure routes so that a request to /checkout/start is correctly routed through the scoped hierarchy.

  7. Use Async Request Handlers for non-blocking external calls

    main

    Gotham supports asynchronous request handlers, allowing you to perform non-blocking operations (such as making web requests to external services or sleeping) within a handler. This ensures that while a handler is waiting for a response from an external source, the thread is not blocked and can continue running other Handlers.

    As demonstrated in the async_handlers example, the structure for performing complex asynchronous tasks (like recursive HTTP calls) is similar to simple async handlers. The key is to package asynchronous operations into futures that can be awaited without blocking the executor.

  8. Use async request handlers for non-blocking operations

    main

    To maintain a high-performance web server, avoid using blocking calls like std::thread::sleep inside request handlers. Instead, return a Future that resolves when the long-running operation (such as a database query, an external API call, or a timer) is complete. This allows Gotham to handle other requests in parallel on the same thread without waiting for the operation to finish.

    When to use futures vs threads:

    • Use Futures: For I/O-bound operations where the server is waiting on another service (e.g., databases, external APIs).
    • Use Threads: For CPU-intensive or memory-intensive operations where the server is actively performing heavy computation.
  9. Use the IntoResponse trait to return data from handlers

    main
    In Gotham, the IntoResponse trait allows you to convert various types (such as JSON, strings, or custom structs) directly into an HTTP response. This simplifies handler logic by letting you return the data you want to send to the client instead of manually constructing a full Response object with status codes and headers.
  10. How the Gotham Diesel Middleware works

    main

    The Gotham Diesel middleware manages database interactions by using tokio_threadpool::blocking. This allows blocking database operations to run on a separate thread pool, preventing them from blocking the main Tokio reactor.

    Key characteristics:

    • Concurrency: It allows multiple concurrent database requests, with a default limit of 100 concurrent blocking operations.
    • Testing: When used in tests, the middleware can utilize isolated test transactions, which enables tests to run in parallel without interfering with each other.
  11. Use a Finalizer to run code before a response is returned

    main
    A Finalizer in Gotham is a mechanism that allows you to execute logic immediately before a response is sent back to the client. This is useful for cross-cutting concerns such as logging, adding custom headers, or handling specific status codes (like 404 Not Found) globally across the application.