Feather:一个跳过Rust异步样板代码的Web框架
Feather: Feather: A web framework that skips Rust's async boilerplate and jus

原始链接: https://github.com/BersisSe/feather

Feather 是一个轻量级且开发者友好的 Rust Web 框架,其灵感来自 Express.js。它优先考虑易用性、模块化以及 Rust 的性能和安全性。核心架构围绕可组合的中间件展开,用于路由、身份验证和日志记录。Feather 通过其 Context API 简化了状态管理,无需复杂的提取器或宏。 Feather 提供内置的 JWT 身份验证(通过特性标志),并拥有出色的工具,例如 Feather-CLI,简化了 API 和 Web 服务器的创建。该框架的模块化设计允许开发者仅选择他们需要的功能,避免不必要的开销。凭借简洁且符合人体工程学的 API,Feather 旨在降低 Rust Web 开发的门槛,同时保持高性能。欢迎贡献代码,项目采用 MIT 许可证。

一个 Hacker News 帖子讨论了 Rust 的 Web 框架 "Feather",它号称可以跳过异步代码的样板。然而,用户批评它单线程的特性,一个测试表明并发请求是顺序处理的,这与 Rust 关注安全并发性的理念相矛盾。一些人建议使用 Rocket 作为更成熟的多线程替代方案,它允许同步代码。 讨论指出 Feather 的中间件方法中 `MiddlewareResult::Next` 的冗余,这使得响应成为副作用而不是返回值。虽然 Feather 可能适合小型项目或教育用途,但其性能限制和设计选择对其实际应用性提出了质疑。该帖子还涉及 Rust 在 Web 服务器性能方面与 Go 等其他语言的比较,以及选择框架时的开发者体验 (DX) 考虑,特别是对于 Rust 新手而言。

原文

Feather is a lightweight, DX-first web framework for Rust — inspired by the simplicity of Express.js, but designed for Rust’s performance and safety.

  • Middleware-First Architecture
    Everything is a middleware — route handlers, auth, logging — all composable and clean.

  • Easy State Management Using Context
    In the recent versions Feather, implemented the Context API that makes it very easy manage state without the use of Extractors/Macros

  • Developer Experience First
    Feather’s API is minimal, ergonomic, and readable

  • Modular and Extensible
    Feather is designed to Modular, only select the features you need and use the. What you don't use you don't pay

  • Great Tooling Out Of the Box
    With the use of the Feather-CLI Creating API's and Web Servers become a Breeze.


Add Feather to your Cargo.toml:

[dependencies]
feather = "0.3.1"

use feather::{App, AppContext, MiddlewareResult,Request, Response};

fn main() {
    let mut app = App::new();
    app.get("/",|_req: &mut Request, res: &mut Response, _ctx: &mut AppContext| {
            res.send_text("Hello, world!");
            MiddlewareResult::Next
    });

    app.listen("127.0.0.1:3000");
}

That’s all — no async,


Middleware is intented to be heart of Feather. You may write it as a closure, a struct, or chain them together:

use feather::{App, AppContext, Request, Response};
use feather::middleware::builtins;
use feather::middleware::{Middleware, MiddlewareResult};
// Implementors of the Middleware trait are middleware that can be used in a Feather app.
struct Custom;
impl Middleware for Custom {
    fn handle(&self,request: &mut Request,_response: &mut Response,_ctx: &mut AppContex) -> MiddlewareResult {
      println!("Now running some custom middleware (struct Custom)!");
      println!("And there's a request with path: {:?}", request.uri);
      MiddlewareResult::Next
    }
}

fn main() {
    let mut app = App::new();
    app.use_middleware(builtins::Logger);
    app.use_middleware(Custom);
    app.use_middleware(|_req: &mut Request, _res: &mut Response, _ctx: &mut AppContext| {
        println!("Now running some custom middleware (closure)!");
        MiddlewareResult::Next
    });

    app.get("/",|_req: &mut Request, res: &mut Response, _ctx: &mut AppContext| {
        res.send_text("Hello, world!");
        MiddlewareResult::Next
    });

    app.listen("127.0.0.1:3000");
}

State Management using the Context API

Feather's new Context API allows you to manage application-wide state without extractors or macros.
As an example:

use feather::{App, AppContext, MiddlewareResult, Response, Request};

struct Counter {
    pub count: i32,
}

fn main() {
    let mut app = App::new();
    let counter = Counter { count: 0 };
    app.context().set_state(counter);

    app.get("/", move |_req: &mut Request, res: &mut Response, ctx: &mut AppContext| {
        let counter: &mut Counter = ctx.get_mut_state::<Counter>().unwrap();
        counter.count += 1;
        res.send_text(format!("Counted! {}", counter.count));
        MiddlewareResult::Next
    });
    app.get("/count", move |_req: &mut Request, res: &mut Response, ctx: &mut AppContext| {
        let counter = ctx.get_state::<Counter>().unwrap();
        res.send_text(counter.count.to_string());
        MiddlewareResult::Next
    });

    app.listen("127.0.0.1:5050");
}

Context Is more useful when combined with Database/File Accesses

Built-in JWT Authentication

Feather has native JWT module activated using a cargo feature jwt:

[dependencies]
feather = { version = "0.3.1", features = ["jwt"] }
use feather::jwt::{generate_jwt, with_jwt_auth};
use feather::{App, AppContext};

fn main() {
    let mut app = App::new();
    app.get("/auth",with_jwt_auth("secretcode", |_req, res,_ctx, claim| {
        println!("Claim: {:?}", claim);
        res.send_text("Hello, JWT!");
        feather::MiddlewareResult::Next
      }),
    );
    // Check the JWT Example for more complete version!
    app.listen("127.0.0.1:8080")
}

  • Being the simplest Rust web framework to get started with
  • Being modular and easy to extend
  • Focusing on DX without sacrificing Rust's safety and performance

PRs welcome!
If you’ve got ideas or bugs, please open an issue or submit a pull request.

# Getting started with dev
git clone https://github.com/BersisSe/feather.git
cd feather
cargo run --example app

Feather is MIT licensed. See LICENSE.


Feather is inspired by Express.js and exists to bring that same productivity to Rust.


If you like Feather:

  • ⭐ Star it on GitHub
  • Share it on Reddit, HN, or Discord
  • Build something and show up!

联系我们 contact @ memedata.com