-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
164 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Getting started | ||
|
||
Rust Web Framework (also called Rwf) has very few dependencies and is easy to install and use. | ||
|
||
## Install Rust | ||
|
||
If you haven't already, install the Rust compiler and tools from [rust-lang.org](https://rust-lang.org). Rwf doesn't use any nightly or experimental features, | ||
so the stable version of the compiler will work. | ||
|
||
## Create a project | ||
|
||
Rwf can be used inside any Rust binary or library project. If you don't have a project already, you can create one with Cargo: | ||
|
||
```bash | ||
cargo init --bin rwf-web-app | ||
``` | ||
|
||
## Install Rwf | ||
|
||
Rwf has two packages: | ||
|
||
* `rwf` which is the Rust crate[^1] used to build web apps | ||
* `rwf-cli` which is a binary application that helps manage Rust projects built with Rwf | ||
|
||
To install them, run the following while inside the root directory of your Cargo-created project: | ||
|
||
``` | ||
cargo add rwf | ||
cargo install rwf-cli | ||
``` | ||
|
||
[^1]: A "crate" is a Rust package used as a dependency in other packages. It's analogous to "package" in JavaScript or Python. | ||
|
||
## Building the app | ||
|
||
With the packages installed, you're ready to launch your first web app in Rust. Rwf is built using the [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model-view-controller) design pattern, | ||
so to get started, let's create a simple controller that will serve the index page (`/`) of your app: | ||
|
||
```rust | ||
use rwf::prelude::*; | ||
|
||
#[derive(Default)] | ||
struct Index; | ||
|
||
#[async_trait] | ||
impl Controller for Index { | ||
async fn handle(&self, request: &Request) -> Result<Response, Error> { | ||
Ok(Response::new().html("<h1>My first Rwf app!</h1>")) | ||
} | ||
} | ||
``` | ||
|
||
`rwf::prelude::*` includes the vast majority of types, structs, traits and functions you'll be using when building controllers with Rwf. | ||
Adding this declaration in your source files will make handling imports easier, but it's not required. | ||
|
||
Rwf controllers are defined as Rust structs which implement the `Controller` trait. The trait is asynchronous, hence the `#[async_trait]` macro[^2], | ||
and has only one method you need to implement: `async fn handle`. This method | ||
acccepts an HTTP `Request`, and must return an HTTP `Response`. | ||
|
||
In this example, we are returning `HTTP 200 - OK` with the body `<h1>My first Rwf app</h1>`. This is not strictly valid HTML, | ||
but it'll work in all browsers for our demo purposes. | ||
|
||
[^2]: The Rust language support for async traits is still incomplete. The `async_trait` crate helps with writing async traits in an ergonomic way. | ||
|
||
## Launching the server | ||
|
||
Once you have at least one controller, you can add it to the Rwf HTTP server and launch it on the address and port of your choosing: | ||
|
||
```rust | ||
use rwf::http::{self, Server}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), http::Error> { | ||
// Configure then logger (stderr with colors by default) | ||
Logger::init(); | ||
|
||
Server::new(vec![ | ||
route!("/" => Index), | ||
]) | ||
.launch("0.0.0.0:8000") | ||
.await | ||
} | ||
``` | ||
|
||
Rwf uses the `log` crate for logging. `Logger::init()` automatically configures it for your app using `env_logger`, but if you prefer, you can configure logging yourself | ||
using the crate of your choosing. | ||
|
||
Once the server is launched, you can visit the index page by pointing your browser to [http://localhost:8000](http://localhost:8000). | ||
|
||
Full code for this is available in GitHub in [examples/quick-start](https://github.com/levkk/rwf/tree/main/examples/quick-start). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Introduction | ||
|
||
[Rwf](https://github.com/levkk/rwf) is a framework for building web applications in the Rust programming language. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
site_name: Rust Web Framework | ||
theme: | ||
name: material | ||
palette: | ||
# Palette toggle for automatic mode | ||
- media: "(prefers-color-scheme)" | ||
toggle: | ||
icon: material/brightness-auto | ||
name: Switch to light mode | ||
|
||
# Palette toggle for light mode | ||
- media: "(prefers-color-scheme: light)" | ||
scheme: default | ||
|
||
toggle: | ||
icon: material/brightness-7 | ||
name: Switch to dark mode | ||
|
||
# Palette toggle for dark mode | ||
- media: "(prefers-color-scheme: dark)" | ||
scheme: slate | ||
toggle: | ||
icon: material/brightness-4 | ||
name: Switch to system preference | ||
docs_dir: docs | ||
markdown_extensions: | ||
- pymdownx.highlight: | ||
anchor_linenums: true | ||
line_spans: __span | ||
pygments_lang_class: true | ||
- pymdownx.inlinehilite | ||
- pymdownx.snippets | ||
- pymdownx.superfences | ||
- footnotes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
babel==2.16.0 | ||
certifi==2024.8.30 | ||
charset-normalizer==3.4.0 | ||
click==8.1.7 | ||
colorama==0.4.6 | ||
ghp-import==2.1.0 | ||
idna==3.10 | ||
Jinja2==3.1.4 | ||
Markdown==3.7 | ||
MarkupSafe==3.0.1 | ||
mergedeep==1.3.4 | ||
mkdocs==1.6.1 | ||
mkdocs-get-deps==0.2.0 | ||
mkdocs-material==9.5.41 | ||
mkdocs-material-extensions==1.3.1 | ||
mkdocs-terminal==4.6.0 | ||
packaging==24.1 | ||
paginate==0.5.7 | ||
pathspec==0.12.1 | ||
platformdirs==4.3.6 | ||
Pygments==2.18.0 | ||
pymdown-extensions==10.11.2 | ||
python-dateutil==2.9.0.post0 | ||
PyYAML==6.0.2 | ||
pyyaml_env_tag==0.1 | ||
regex==2024.9.11 | ||
requests==2.32.3 | ||
six==1.16.0 | ||
urllib3==2.2.3 | ||
watchdog==5.0.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,21 @@ | ||
use rwf::http::Server; | ||
use rwf::http::{self, Server}; | ||
use rwf::prelude::*; | ||
|
||
#[derive(Default)] | ||
struct IndexController; | ||
struct Index; | ||
|
||
#[async_trait] | ||
impl Controller for IndexController { | ||
async fn handle(&self, _request: &Request) -> Result<Response, Error> { | ||
Ok(Response::new().html("<h1>Hey Rum!</h1>")) | ||
impl Controller for Index { | ||
async fn handle(&self, request: &Request) -> Result<Response, Error> { | ||
Ok(Response::new().html("<h1>My first Rwf app!</h1>")) | ||
} | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
async fn main() -> Result<(), http::Error> { | ||
Logger::init(); | ||
|
||
Server::new(vec![IndexController::default().route("/")]) | ||
Server::new(vec![route!("/" => Index)]) | ||
.launch("0.0.0.0:8000") | ||
.await | ||
.expect("error shutting down server"); | ||
} |