{"id":20292377,"url":"https://github.com/ladroid/parfait","last_synced_at":"2025-04-11T11:22:28.889Z","repository":{"id":225865724,"uuid":"755720532","full_name":"ladroid/Parfait","owner":"ladroid","description":"Most lightweight and easy to use RESTful web framework","archived":false,"fork":false,"pushed_at":"2024-04-07T21:08:00.000Z","size":1234,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T07:41:36.829Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ladroid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-10T22:03:31.000Z","updated_at":"2024-03-14T22:21:41.000Z","dependencies_parsed_at":"2024-03-04T18:58:32.686Z","dependency_job_id":null,"html_url":"https://github.com/ladroid/Parfait","commit_stats":null,"previous_names":["ladroid/parfait"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladroid%2FParfait","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladroid%2FParfait/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladroid%2FParfait/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladroid%2FParfait/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ladroid","download_url":"https://codeload.github.com/ladroid/Parfait/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248382127,"owners_count":21094541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2024-11-14T15:17:01.233Z","updated_at":"2025-04-11T11:22:28.864Z","avatar_url":"https://github.com/ladroid.png","language":"Rust","readme":"# Parfait\r\n\r\n\u003cp align=\"center\"\u003e\r\n    \u003cimg src=\"logo/logo.png\" width=\"300\" height=\"300\" /\u003e\r\n\u003c/p\u003e\r\n\r\nParfait (/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.\r\n\r\nParfait depends on several libraries - serde for JSON and tokio for asynchronous.\r\n\r\n## Goal\r\n\r\nThe 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.\r\n\r\n### Macro-Based Approach\r\n\r\nParfait 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.\r\n\r\n### Comparison with Rocket\r\n\r\n[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.\r\n\r\nIn 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.\r\n\r\n### Comparison with Actix\r\n\r\n[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.\r\n\r\nUnlike 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.\r\n\r\n## How to use\r\n\r\n1. Input and output result:\r\n\r\n```rust\r\n// Define a handler for the input form\r\nget!(\"/\", home_handler =\u003e r#\"src\\input.html\"#, \"HTTP/1.1 200 OK\\r\\nContent-Type: text/html\\r\\n\\r\\n\");\r\n\r\n// Define a handler for the result page\r\npost!(\"/result\", result_handler =\u003e \"src/output.html\", \"text/html\"); // For HTML response\r\n...\r\nget_handler: Some(|path, query| home_handler(path, query, None)),\r\npost_handler: Some(|path, query, body| result_handler(path, query, Some(body))),\r\n```\r\n\r\n**Note** fields in the Handler can accept None type. For example:\r\n\r\n```rust\r\n....\r\nlet handler = Handler {\r\n    get_handler: Some(|path, query| home_handler(path, query, None)),\r\n    post_handler: Some(|path, query, body| result_handler(path, query, Some(body))),\r\n};\r\n```\r\n\r\nMore details can be found [here](examples/test/test.rs)\r\n\r\n2. Loop:\r\n\r\n```rust\r\npost!(\"/loop\", result_handler =\u003e r#\"examples\\test5\\loop.html\"#, \"text/html\");\r\n...\r\npost_handler: Some(|_, _, _| {\r\n    // Read the file content\r\n    match std::fs::read_to_string(\"examples\\\\test5\\\\loop.html\") {\r\n        Ok(file_content) =\u003e {\r\n            let items = vec![\"Item 1\", \"Item 2\", \"Item 3\"];\r\n            let mut result = String::new();\r\n            let mut in_for_loop = false;\r\n            \r\n            for line in file_content.lines() {\r\n                if line.contains(\"{% for item in items %}\") {\r\n                    in_for_loop = true;\r\n                    for item in \u0026items {\r\n                        result.push_str(\u0026line.replace(\"{% for item in items %}\", \u0026format!(\"{}\", item)));\r\n                        result.push_str(\"\\n\");\r\n                    }\r\n                } else if in_for_loop \u0026\u0026 line.contains(\"{% endfor %}\") {\r\n                    in_for_loop = false;\r\n                }\r\n            }\r\n            Some(format!(\"HTTP/1.1 200 OK\\r\\nContent-Type: text/html\\r\\n\\r\\n{}\", result))\r\n        },\r\n        Err(_) =\u003e Some(\"HTTP/1.1 500 INTERNAL SERVER ERROR\\r\\n\\r\\nFailed to read file\".to_owned()),\r\n    }\r\n}),\r\n```\r\n\r\nMore details can be found [here](examples/test5/test5.rs)\r\n\r\n3. Using URL path:\r\n\r\n```rust\r\n// Define a handler for the input form\r\nget!(\"/hello/\", home_handler =\u003e r#\"src\\input.html\"#, \"HTTP/1.1 200 OK\\r\\nContent-Type: text/html\\r\\n\\r\\n\");\r\n\r\n// Define a handler for the result page\r\npost!(\"/hello/result\", result_handler =\u003e r#\"src\\output.html\"#, \"text/html\");\r\n```\r\n\r\n4. JSON\r\n\r\n```rust\r\npost!(\"/path\", handle_post =\u003e r#\"src\\file.json\"#, |_, _| {\r\n    match std::fs::read_to_string(\"src\\\\file.json\") {\r\n        Ok(content) =\u003e {\r\n            if let Some(json_data) = paprika::parse_json(\u0026content) {\r\n                let response_json = paprika::generate_json_response(json_data);\r\n                Some(format!(\"HTTP/1.1 200 OK\\r\\nContent-Type: application/json\\r\\n\\r\\n{}\", response_json))\r\n            } else {\r\n                Some(\"HTTP/1.1 500 INTERNAL SERVER ERROR\\r\\n\\r\\nFailed to parse JSON\".to_owned())\r\n            }\r\n        },\r\n        Err(_) =\u003e Some(\"HTTP/1.1 500 INTERNAL SERVER ERROR\\r\\n\\r\\nFailed to read file\".to_owned()),\r\n    }\r\n});\r\n```\r\n\r\nMore details can be found [here](examples/test4/test4.rs)\r\n\r\n## Features\r\n\r\n✅ post\r\n\r\n✅ get\r\n\r\n✅ put\r\n\r\n✅ delete\r\n\r\n✅ Handling get/post requests\r\n\r\n✅ Compatibility with third-party libraries such as serde for JSON\r\n\r\n✅ Error handling\r\n\r\n✅ JSON\r\n\r\n✅ Possibility to work with query\r\n\r\n✅ Middleware\r\n\r\n## Contributing\r\n\r\nContributions are absolutely, positively welcome and encouraged! Contributions\r\ncome in many forms. You could:\r\n\r\n  1. Submit a feature request or bug report as an [issue].\r\n  2. Ask for improved documentation as an [issue].\r\n  3. Comment on issues that require feedback.\r\n  4. Contribute code via [pull requests].\r\n\r\n[issue]: https://github.com/ladroid/Parfait/issues\r\n[pull requests]: https://github.com/ladroid/Parfait/pulls\r\n\r\n## License\r\n\r\nParfait is licensed under Apache license version 2.0. See [LICENSE](https://github.com/ladroid/Parfait/blob/main/LICENSE) file.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fladroid%2Fparfait","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fladroid%2Fparfait","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fladroid%2Fparfait/lists"}