Crate rupring

Source
Expand description

§Get Started

There is only one dependency.

cargo add rupring

And you can write your server like this:

#[derive(Debug, Clone, Copy)]
#[rupring::Module(controllers=[HomeController{}], modules=[])]
pub struct RootModule {}

#[derive(Debug, Clone)]
#[rupring::Controller(prefix=/, routes=[hello, echo])]
pub struct HomeController {}

#[rupring::Get(path = /)]
pub fn hello(_request: rupring::Request) -> rupring::Response {
    rupring::Response::new().text("Hello, World!".to_string())
}

#[rupring::Get(path = /echo)]
pub fn echo(request: rupring::Request) -> rupring::Response {
    rupring::Response::new().text(request.body)
}

fn main() {
    rupring::run(RootModule {})
}

§Request

  • rupring defines HTTP Request through crate::request::Request type and provides convenient request processing using macros.
#[rupring::Get(path = /:id)]
pub fn hello(request: rupring::Request) -> rupring::Response {
    let method = request.method;
    assert_eq!(method, rupring::Method::GET);

    let path = request.path;
    assert_eq!(path, "/");

    let body = request.body;
    assert_eq!(body, "");

    let headers = request.headers;
    let content_type = headers.get("content-type").unwrap();
    assert_eq!(content_type, "text/plain");

    let id = request.path_parameters["id"].clone();
    assert_eq!(id, "123");

    let query = request.query_parameters["query"].clone();
    assert_eq!(query, vec!["asdf".to_string()]);

    //...

    response
}
  • Please refer to the corresponding document for more details.

§Response

  • rupring defines HTTP Response through crate::response::Response type and provides convenient response processing using macros.
#[rupring::Get(path = /)]
pub fn hello(_request: rupring::Request) -> rupring::Response {
    rupring::Response::new().text("Hello, World!".to_string())
}
  • Please refer to the corresponding document for more details.

§Middleware

rupring provides middleware features for common logic processing.

If you want to log requests for all APIs that exist in a module, you can apply middleware in the form below.

First, define a middleware function.

pub fn logger_middleware(
    request: rupring::Request,
    response: rupring::Response,
    next: rupring::NextFunction,
) -> rupring::Response {
    println!(
        "Request: {} {}",
        request.method.to_string(),
        request.path.to_string()
    );

    next(request, response)
}

The above function only records logs and forwards them to the next middleware or route function. If you want to return a response immediately without forwarding, just return the response without calling the next function.

And you can register the middleware function just defined in the module or controller unit.

pub fn logger_middleware(
    request: rupring::Request,
    response: rupring::Response,
    next: rupring::NextFunction,
) -> rupring::Response {
    println!(
        "Request: {} {}",
        request.method.to_string(),
        request.path.to_string()
    );

    next(request, response)
}

#[derive(Debug, Clone, Copy)]
#[rupring::Module(
    controllers=[RootController{}],
    modules=[UserModule{}],
    providers=[],
    middlewares=[logger_middleware]
)]
pub struct RootModule {}

#[derive(Debug, Clone)]
#[rupring::Controller(prefix=/, routes=[])]
pub struct RootController {}

#[derive(Debug, Clone, Copy)]
#[rupring::Module(
    controllers=[UserController{}],
    providers=[],
    middlewares=[]
)]
pub struct UserModule {}

// or Controller
#[derive(Debug, Clone)]
#[rupring::Controller(prefix=/, routes=[], middlewares=[logger_middleware])]
pub struct UserController {}

Middleware registered in a module is recursively applied to the routes of controllers registered in that module and to child modules. On the other hand, middleware registered in a controller applies only to the routes of that controller.

The priorities in which middleware is applied are as follows:

  1. Middleware of the same unit is executed in the order defined in the array.
  2. If module middleware and controller middleware exist at the same time, module middleware is executed first.
  3. If the parent module’s middleware and the child module’s middleware exist at the same time, the parent module middleware is executed first.

§Dependency Injection

  • Rupring provides powerful DI features through macro and runtime support.
#[derive(Debug, Clone, Default)]
pub struct HomeService {}

impl HomeService {
    pub fn hello(&self) -> String {
        "hello!!".to_string()
    }
}

impl rupring::IProvider for HomeService {
    fn provide(&self, di_context: &rupring::DIContext) -> Box<dyn std::any::Any> {
        Box::new(HomeService {})
    }
}
  • Please refer to the corresponding document for more details.

§Swagger

  • When rupring starts the server, it automatically serves swagger documents to the /docs path.
  • Please refer to the corresponding document for more details.

§Application Properties

  • rupring provides various execution options through a special configuration file called application.properties.
  • Please refer to the corresponding document for more details.

§AWS Lambda

  • rupring provides the option to run on AWS Lambda.
  • Supported Lambda Runtimes
    1. Amazon Linux 2
    2. Amazon Linux 2023

§How to use

  1. Enable the “aws-lambda” feature flag.
rupring={ version = "0.12.0", features=["aws-lambda"] }
  1. Use the rupring::run_on_aws_lambda function instead of rupring::run.
fn main() {
    rupring::run_on_aws_lambda(RootModule {})
}
  1. Compile and create an executable file. (x86_64-unknown-linux-musl)
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
  1. Zip the executable file and upload it to the AWS console.
  • The name of the executable file must be bootstrap.
zip -j bootstrap.zip ./target/x86_64-unknown-linux-musl/release/bootstrap
  1. …and upload it as a file to the AWS console

Re-exports§

Modules§

Macros§

  • Construct an ad-hoc error from a string or existing non-anyhow error value.

Structs§

Traits§

Functions§

  • shortcut to run the application

Type Aliases§

Attribute Macros§

Derive Macros§