RustApi

Struct RustApi 

Source
pub struct RustApi { /* private fields */ }
Expand description

Main application builder for RustAPI

§Example

use rustapi_rs::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    RustApi::new()
        .state(AppState::new())
        .route("/", get(hello))
        .route("/users/{id}", get(get_user))
        .run("127.0.0.1:8080")
        .await
}

Implementations§

Source§

impl RustApi

Source

pub fn new() -> RustApi

Create a new RustAPI application

Source

pub fn auto() -> RustApi

Create a zero-config RustAPI application.

All routes decorated with #[rustapi::get], #[rustapi::post], etc. are automatically registered. Swagger UI is enabled at /docs by default.

§Example
use rustapi_rs::prelude::*;

#[rustapi::get("/users")]
async fn list_users() -> Json<Vec<User>> {
    Json(vec![])
}

#[rustapi::main]
async fn main() -> Result<()> {
    // Zero config - routes are auto-registered!
    RustApi::auto()
        .run("0.0.0.0:8080")
        .await
}
Source

pub fn config() -> RustApiConfig

Create a configurable RustAPI application with auto-routes.

Provides builder methods for customization while still auto-registering all decorated routes.

§Example
use rustapi_rs::prelude::*;

RustApi::config()
    .docs_path("/api-docs")
    .body_limit(5 * 1024 * 1024)  // 5MB
    .openapi_info("My API", "2.0.0", Some("API Description"))
    .run("0.0.0.0:8080")
    .await?;
Source

pub fn body_limit(self, limit: usize) -> RustApi

Set the global body size limit for request bodies

This protects against denial-of-service attacks via large payloads. The default limit is 1MB (1024 * 1024 bytes).

§Arguments
  • limit - Maximum body size in bytes
§Example
use rustapi_rs::prelude::*;

RustApi::new()
    .body_limit(5 * 1024 * 1024)  // 5MB limit
    .route("/upload", post(upload_handler))
    .run("127.0.0.1:8080")
    .await
Source

pub fn no_body_limit(self) -> RustApi

Disable the body size limit

Warning: This removes protection against large payload attacks. Only use this if you have other mechanisms to limit request sizes.

§Example
RustApi::new()
    .no_body_limit()  // Disable body size limit
    .route("/upload", post(upload_handler))
Source

pub fn layer<L>(self, layer: L) -> RustApi
where L: MiddlewareLayer,

Add a middleware layer to the application

Layers are executed in the order they are added (outermost first). The first layer added will be the first to process the request and the last to process the response.

§Example
use rustapi_rs::prelude::*;
use rustapi_core::middleware::{RequestIdLayer, TracingLayer};

RustApi::new()
    .layer(RequestIdLayer::new())  // First to process request
    .layer(TracingLayer::new())    // Second to process request
    .route("/", get(handler))
    .run("127.0.0.1:8080")
    .await
Source

pub fn state<S>(self, _state: S) -> RustApi
where S: Clone + Send + Sync + 'static,

Add application state

State is shared across all handlers and can be extracted using State<T>.

§Example
#[derive(Clone)]
struct AppState {
    db: DbPool,
}

RustApi::new()
    .state(AppState::new())
Source

pub fn register_schema<T>(self) -> RustApi
where T: for<'a> ToSchema<'a>,

Register an OpenAPI schema

§Example
#[derive(Schema)]
struct User { ... }

RustApi::new()
    .register_schema::<User>()
Source

pub fn openapi_info( self, title: &str, version: &str, description: Option<&str>, ) -> RustApi

Configure OpenAPI info (title, version, description)

Source

pub fn openapi_spec(&self) -> &OpenApiSpec

Get the current OpenAPI spec (for advanced usage/testing).

Source

pub fn route(self, path: &str, method_router: MethodRouter) -> RustApi

Add a route

§Example
RustApi::new()
    .route("/", get(index))
    .route("/users", get(list_users).post(create_user))
    .route("/users/{id}", get(get_user).delete(delete_user))
Source

pub fn mount(self, path: &str, method_router: MethodRouter) -> RustApi

👎Deprecated: Use route() directly or mount_route() for macro-based routing

Mount a handler (convenience method)

Alias for .route(path, method_router) for a single handler.

Source

pub fn mount_route(self, route: Route) -> RustApi

Mount a route created with #[rustapi::get], #[rustapi::post], etc.

§Example
use rustapi_rs::prelude::*;

#[rustapi::get("/users")]
async fn list_users() -> Json<Vec<User>> {
    Json(vec![])
}

RustApi::new()
    .mount_route(route!(list_users))
    .run("127.0.0.1:8080")
    .await
Source

pub fn nest(self, prefix: &str, router: Router) -> RustApi

Nest a router under a prefix

All routes from the nested router will be registered with the prefix prepended to their paths. OpenAPI operations from the nested router are also propagated to the parent’s OpenAPI spec with prefixed paths.

§Example
let api_v1 = Router::new()
    .route("/users", get(list_users));

RustApi::new()
    .nest("/api/v1", api_v1)
Source

pub fn serve_static(self, prefix: &str, root: impl Into<PathBuf>) -> RustApi

Serve static files from a directory

Maps a URL path prefix to a filesystem directory. Requests to paths under the prefix will serve files from the corresponding location in the directory.

§Arguments
  • prefix - URL path prefix (e.g., “/static”, “/assets”)
  • root - Filesystem directory path
§Features
  • Automatic MIME type detection
  • ETag and Last-Modified headers for caching
  • Index file serving for directories
  • Path traversal prevention
§Example
use rustapi_rs::prelude::*;

RustApi::new()
    .serve_static("/assets", "./public")
    .serve_static("/uploads", "./uploads")
    .run("127.0.0.1:8080")
    .await
Source

pub fn serve_static_with_config(self, config: StaticFileConfig) -> RustApi

Serve static files with custom configuration

§Example
use rustapi_core::static_files::StaticFileConfig;

let config = StaticFileConfig::new("./public", "/assets")
    .max_age(86400)  // Cache for 1 day
    .fallback("index.html");  // SPA fallback

RustApi::new()
    .serve_static_with_config(config)
    .run("127.0.0.1:8080")
    .await
Source

pub fn docs(self, path: &str) -> RustApi

Enable Swagger UI documentation

This adds two endpoints:

  • {path} - Swagger UI interface
  • {path}/openapi.json - OpenAPI JSON specification
§Example
RustApi::new()
    .route("/users", get(list_users))
    .docs("/docs")  // Swagger UI at /docs, spec at /docs/openapi.json
    .run("127.0.0.1:8080")
    .await
Source

pub fn docs_with_info( self, path: &str, title: &str, version: &str, description: Option<&str>, ) -> RustApi

Enable Swagger UI documentation with custom API info

§Example
RustApi::new()
    .docs_with_info("/docs", "My API", "2.0.0", Some("API for managing users"))
Source

pub fn docs_with_auth( self, path: &str, username: &str, password: &str, ) -> RustApi

Enable Swagger UI documentation with Basic Auth protection

When username and password are provided, the docs endpoint will require Basic Authentication. This is useful for protecting API documentation in production environments.

§Example
RustApi::new()
    .route("/users", get(list_users))
    .docs_with_auth("/docs", "admin", "secret123")
    .run("127.0.0.1:8080")
    .await
Source

pub fn docs_with_auth_and_info( self, path: &str, username: &str, password: &str, title: &str, version: &str, description: Option<&str>, ) -> RustApi

Enable Swagger UI documentation with Basic Auth and custom API info

§Example
RustApi::new()
    .docs_with_auth_and_info(
        "/docs",
        "admin",
        "secret",
        "My API",
        "2.0.0",
        Some("Protected API documentation")
    )
Source

pub async fn run(self, addr: &str) -> Result<(), Box<dyn Error + Send + Sync>>

Run the server

§Example
RustApi::new()
    .route("/", get(hello))
    .run("127.0.0.1:8080")
    .await
Source

pub fn into_router(self) -> Router

Get the inner router (for testing or advanced usage)

Source

pub fn layers(&self) -> &LayerStack

Get the layer stack (for testing)

Trait Implementations§

Source§

impl Default for RustApi

Source§

fn default() -> RustApi

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more