Skip to content
/ pavex Public
forked from LukeMathWalker/pavex

An easy-to-use Rust framework for building robust and performant APIs

License

Notifications You must be signed in to change notification settings

etiescu/pavex

 
 

Repository files navigation

pavex pavex
Re-imagining backend development in Rust

What is Pavex?

Pavex is a new framework to build APIs with Rust.

Pavex aims to have it all: great ergonomics and high performance.
The same productivity boost of Ruby on Rails, Spring or ASP.NET Core.
As fast as a handwritten solution that strips away all abstractions.

Pavex takes a significantly different approach compared to the current generation of Rust web frameworks: you can think of Pavex as a specialised compiler for building Rust APIs.
It takes as input a high-level description of what your application should do, a Blueprint:

pub fn app_blueprint() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.constructor(f!(crate::http_client), Lifecycle::Singleton);
    bp.constructor(f!(crate::extract_path), Lifecycle::RequestScoped);
    bp.constructor(f!(crate::logger), Lifecycle::Transient);
    bp.route(GET, "/home", f!(crate::stream_file));
    bp
}

It generates as output a standalone API server SDK crate, behaving according to your specification, ready to be configured and launched.

Great error messages

Pavex operates at the right level of abstraction—it understands the specific challenges and requirements of API development.
The intermediate code generation step (Blueprint -> runtime code) allows Pavex to perform in-depth static analysis. Potential issues are caught at compile-time with an informative error message:

ERROR:
  × `app::get_home` is trying to extract route parameters using `RouteParams<HomeRouteParams>`.
  │ Every struct field in `app::HomeRouteParams` must be named after one of the route parameters 
  | that appear in `/address/:address_id/home/:home_id`:
  │ - `home_id`
  │ - `address_id`
  │
  │ There is no route parameter named `street_id`, but there is a struct field named
  │ `street_id` in `app::HomeRouteParams`. This is going to cause a runtime error!
  │
  │     ╭─[src/lib.rs:43:1]
  │  43 │     ));
  │  44 │     bp.route(GET, "/home/:id", f!(crate::get_home));
  │     ·                                ───────────┬──────
  │     ·             The request handler asking for `RouteParams<app::HomeRouteParams>`
  │  45 │     
  │     ╰────
  │   help: Remove or rename the fields that do not map to a valid route parameter.

Compile-time dependency injection

Your Blueprint tells Pavex:

  • What routes should be exposed;
  • What components can be built, what inputs they need and what is their lifecycle;
  • How to handle errors.

Pavex uses this information to perform compile-time dependency injection.

Each endpoint gets its own call graph and Pavex makes sure to exclusively build what is required to invoke every single endpoint, avoiding unnecessary computations.

flowchart TB
    handler["app::stream_file(Pathbuf, Logger, &Client)"]
    client[Client]
    logger["logger() -> Logger"]
    state[ServerState]
    path["extract_path(&RequestHead)->PathBuf"]
    request[RequestHead]

    state --> client
    client --&--> handler
    logger --> handler
    path --> handler
    request --&--> path
Loading

You write straight-forward Rust, Pavex takes care of assembling together all the components.

Project status

Pavex is under active development and far from being ready for hobby or production usage.
It has not yet been released on crates.io and you can expect breaking changes on every commit to the main branch.

The project is currently in closed beta—you can sign up here to get early access.

We regularly publish project updates:

Examples

You can see Pavex at work in the /examples folder:

In examples/skeleton/blueprint.ron you can have a peek at what the Blueprint looks like when serialized.

Architectural Overview

If the section above was enough to get you intrigued, you can check out the architectural deep-dive in ARCHITECTURE.md to learn how Pavex works under the hood.

Contributing

This project is not open to unsolicited code contributions (for the time being).
If you want to play around with it, you can find instructions in CONTRIBUTING.md.

License

Licensed under the Apache License, Version 2.0. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

About

An easy-to-use Rust framework for building robust and performant APIs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 99.9%
  • Shell 0.1%