
The videos goes over the agenda and discusses why you may want to consider learning and using rust
use axum::{
routing::{get},Router,
};
use tower_http::cors::{Any, CorsLayer};
#[tokio::main]
async fn main() {
//tracing
tracing_subscriber::fmt::init();
// add cors
let cors = CorsLayer::new()
.allow_origin(Any);
let app = Router::new()
.route("/", get(root))
.layer(cors);
tracing::debug!("listening on {}", "0.0.0.0:3000");
println!(" Listening on port {}" , "0.0.0.0:3000" );
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, REST AXUM API"
}
Cargo.toml
[package]
name = "frontend"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
yew = { version = "0.20.0", features = ["csr"] }
yew-router = "0.17"
serde = "1.0.152"
serde_json = "1.0.91"
wasm-bindgen-futures = "0.4.33"
reqwest = { version = "0.11.13", features = ["json"] }
web-sys = {version = "0.3.60", features = ["HtmlInputElement"] }
gloo-console = "0.2.3"
below is the final products.rs file
use serde::{Deserialize, Serialize};
use yew::prelude::*;
use yew_router::prelude::*;
use crate::router::Route;
#[derive(Serialize, Deserialize, Debug)]
pub struct Product {
id: i32,
name: String,
price: i32
}
#[function_component]
pub fn Products() -> Html {
let data: UseStateHandle<Vec<Product>> = use_state(|| vec![]);
{
let data_clone = data.clone();
use_effect(move ||{
wasm_bindgen_futures::spawn_local( async move {
let fetched_data = reqwest::get("http://localhost:3000/api/products")
.await
.expect("cannot get data from url")
.json::<Vec<Product>>()
.await
.expect("cannot convert to json");
data_clone.set(fetched_data);
});
|| ()
});
}
let products = data.iter().map(|product| html! {
<ul>
<li key={product.id}>{format!("Name: {}, Price: {}", product.name, product.price)}</li>
</ul>
}).collect::<Html>();
html! {
<div class="container">
<button class="btn-primary">
<Link<Route> to={Route::AddProduct}>{ "Add new Product" }</Link<Route>>
</button>
<h2>{"List of Products: "} {data.len()} </h2>
<p>{products}</p>
</div>
}
}
let products = data.iter().map(|product| html! {
<ul>
<li key={product.id}>{format!("Name: {}, Price: {}", product.name, product.price)}</li>
</ul>
}).collect::<Html>();
===================================
#### Connecting frontend and server ####
create and add to Cargo.toml
[workspace]
members = [
"server", "frontend"
]
#create and add to .gitignore
target/
dist/
.env
create frontend/Trunk.toml and add contents
[build]
target = "index.html"
dist = "../dist"
now you can run: trunk serve
# now go to server/main.rs
axum::response::IntoResponse
axum::http::StatusCode,
use std::io;
//serving frontend static files
let serve_dir = ServeDir::new("../frontend/dist").not_found_service(ServeFile::new("../dist/frontend/index.html"));
let serve_dir = get_service(serve_dir).handle_error(handle_error);
# add to router
.nest_service("/", serve_dir.clone())
.fallback_service(serve_dir.clone());
# add handle error fn
async fn handle_error(_err: io::Error) -> impl IntoResponse {
(StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong...")
}
# change current / to /home
cd into backend: cargo watch -x run
=========================================
final router.rs
use yew_router::prelude::*;
use yew::prelude::*;
use crate::products::Products;
use crate::form::Form;
#[derive(Clone, Routable, PartialEq)]
pub enum Route {
#[at("/")]
Home,
#[at("/addproduct")]
AddProduct,
#[at("/about")]
About,
#[not_found]
#[at("/404")]
NotFound,
}
pub fn switch(routes: Route) -> Html {
match routes {
Route::Home => html! { <Products /> },
Route::AddProduct => html! { <Form />},
Route::About => html! { <h1>{ "About us " }</h1>},
Route::NotFound => html! { <h1>{ "404" }</h1> },
}
}
You will build a full-stack web app using the rust programming language. We will be building a fully functional CRUD Server API using AXUM, SQLx, and Postgres. Then we will build a fully functional frontend in rust using the Yew framework (Yew looks like ReactJS but in Rust). We will then connect the front end and the back end to run from the same port/URL. You will learn how to create Yew components, routing, create forms and handle GET and POST requests using the rust reqwest crate in the front end. This course is good for developers who already know at least one programming language and have some web development experience. It is not a course for folks who are completely new to programming.
Rust is the most loved programming language for the past several years according to StackOverflow. All the big tech companies are now using rust and a lot of startups are using rust. More so, a lot of the newer blockchain projects are building with rust. The rust programming language is growing very rapidly.
This course will help you start developing in rust very fast, as you will build a real full-stack app. You can use the concepts to expand your rust dev options.
The course is divided into 3 main sections. Section 1 is an intro to rust. You can skip this section if you are already familiar with the material. Section 2 will cover the Server API dev using AXUM and section 3 covers developing frontend apps using the popular Yew framework.
Full source code provided at the end of the course.