Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ladroid/parfait
Most lightweight and easy to use RESTful web framework
https://github.com/ladroid/parfait
async asyncio framework http-requests http-server macro macros macros-rust programming rest rest-api restful-api rust tokio tokio-rs web web-development web-framework webdevelopment
Last synced: 6 days ago
JSON representation
Most lightweight and easy to use RESTful web framework
- Host: GitHub
- URL: https://github.com/ladroid/parfait
- Owner: ladroid
- License: apache-2.0
- Created: 2024-02-10T22:03:31.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2024-04-07T21:08:00.000Z (8 months ago)
- Last Synced: 2024-10-31T12:09:16.191Z (20 days ago)
- Topics: async, asyncio, framework, http-requests, http-server, macro, macros, macros-rust, programming, rest, rest-api, restful-api, rust, tokio, tokio-rs, web, web-development, web-framework, webdevelopment
- Language: Rust
- Homepage:
- Size: 1.18 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Parfait
Parfait (/pɑːrˈfeɪ/ par-FAY) is the most lightweight web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.
Parfait depends on several libraries - serde for JSON and tokio for asynchronous.
## Goal
The goal of Parfait is to provide a lightweight yet powerful solution for building web applications in Rust. While there are established frameworks like Rocket and Actix available, Parfait aims to offer a unique approach tailored to specific use cases and preferences.
### Macro-Based Approach
Parfait utilizes macros for defining `get` and `post` endpoints, etc. This decision was made to simplify the process of defining HTTP routes and handling requests. By using macros, developers can define routes in a concise and readable manner, reducing boilerplate code and improving code maintainability. Additionally, macros allow for compile-time validation of route definitions, catching errors early in the development process. Overall, the use of macros enhances developer productivity and contributes to the framework's goal of providing a lightweight and developer-friendly solution for building web applications in Rust.
### Comparison with Rocket
[Rocket](https://rocket.rs/) is a feature-rich web framework for Rust known for its ease of use and extensive capabilities. It provides a robust set of features out of the box, including routing, request parsing, and response generation, making it suitable for a wide range of web applications.
In comparison, Parfait takes a more minimalist approach, focusing on simplicity and flexibility. While Rocket excels in providing a comprehensive set of features, Parfait prioritizes lightweightness and customization. It aims to provide developers with more control over the components they use, allowing for greater flexibility in building web applications.
### Comparison with Actix
[Actix](https://actix.rs/) is a high-performance, actor-based framework for building concurrent and scalable web applications in Rust. It leverages the actor model to achieve high concurrency and asynchronous processing, making it suitable for applications with demanding performance requirements.
Unlike Actix, Parfait does not adopt the actor model and does not prioritize achieving the same level of concurrency and scalability. Instead, it focuses on simplicity and ease of use while still providing sufficient performance for most web applications. Parfait is designed to be approachable for developers new to Rust web development, offering straightforward abstractions and clear documentation.
## How to use
1. Input and output result:
```rust
// Define a handler for the input form
get!("/", home_handler => r#"src\input.html"#, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");// Define a handler for the result page
post!("/result", result_handler => "src/output.html", "text/html"); // For HTML response
...
get_handler: Some(|path, query| home_handler(path, query, None)),
post_handler: Some(|path, query, body| result_handler(path, query, Some(body))),
```**Note** fields in the Handler can accept None type. For example:
```rust
....
let handler = Handler {
get_handler: Some(|path, query| home_handler(path, query, None)),
post_handler: Some(|path, query, body| result_handler(path, query, Some(body))),
};
```More details can be found [here](examples/test/test.rs)
2. Loop:
```rust
post!("/loop", result_handler => r#"examples\test5\loop.html"#, "text/html");
...
post_handler: Some(|_, _, _| {
// Read the file content
match std::fs::read_to_string("examples\\test5\\loop.html") {
Ok(file_content) => {
let items = vec!["Item 1", "Item 2", "Item 3"];
let mut result = String::new();
let mut in_for_loop = false;
for line in file_content.lines() {
if line.contains("{% for item in items %}") {
in_for_loop = true;
for item in &items {
result.push_str(&line.replace("{% for item in items %}", &format!("{}", item)));
result.push_str("\n");
}
} else if in_for_loop && line.contains("{% endfor %}") {
in_for_loop = false;
}
}
Some(format!("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n{}", result))
},
Err(_) => Some("HTTP/1.1 500 INTERNAL SERVER ERROR\r\n\r\nFailed to read file".to_owned()),
}
}),
```More details can be found [here](examples/test5/test5.rs)
3. Using URL path:
```rust
// Define a handler for the input form
get!("/hello/", home_handler => r#"src\input.html"#, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");// Define a handler for the result page
post!("/hello/result", result_handler => r#"src\output.html"#, "text/html");
```4. JSON
```rust
post!("/path", handle_post => r#"src\file.json"#, |_, _| {
match std::fs::read_to_string("src\\file.json") {
Ok(content) => {
if let Some(json_data) = paprika::parse_json(&content) {
let response_json = paprika::generate_json_response(json_data);
Some(format!("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{}", response_json))
} else {
Some("HTTP/1.1 500 INTERNAL SERVER ERROR\r\n\r\nFailed to parse JSON".to_owned())
}
},
Err(_) => Some("HTTP/1.1 500 INTERNAL SERVER ERROR\r\n\r\nFailed to read file".to_owned()),
}
});
```More details can be found [here](examples/test4/test4.rs)
## Features
✅ post
✅ get
✅ put
✅ delete
✅ Handling get/post requests
✅ Compatibility with third-party libraries such as serde for JSON
✅ Error handling
✅ JSON
✅ Possibility to work with query
✅ Middleware
## Contributing
Contributions are absolutely, positively welcome and encouraged! Contributions
come in many forms. You could:1. Submit a feature request or bug report as an [issue].
2. Ask for improved documentation as an [issue].
3. Comment on issues that require feedback.
4. Contribute code via [pull requests].[issue]: https://github.com/ladroid/Parfait/issues
[pull requests]: https://github.com/ladroid/Parfait/pulls## License
Parfait is licensed under Apache license version 2.0. See [LICENSE](https://github.com/ladroid/Parfait/blob/main/LICENSE) file.