I am thrilled and proud of the progress made in integrating the best tools for modern application development. After tackling multiple challenges, I successfully created a containerized full-stack app with Rust powering the backend and React driving the frontend. Containerizing it with Docker ensures smooth deployments and scalability.
A Solved Code
Here’s a complete guide and code implementation for a Rust backend, React frontend, and Docker containerization.
Backend in Rust (Using Actix-Web Framework)
main.rs
:
codeuse actix_web::{web, App, HttpResponse, HttpServer, Responder};
async fn get_items() -> impl Responder {
HttpResponse::Ok().json(vec![
{"name": "MacBook Pro", "price": 100000},
{"name": "Pendrive", "price": 4000},
{"name": "Mobile", "price": 35000},
])
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().route("/items", web::get().to(get_items))
})
.bind("0.0.0.0:8080")?
.run()
.await
}
Dependencies (in Cargo.toml
):
code[dependencies]
actix-web = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Frontend in React
Install Dependencies:
codenpx create-react-app frontend
cd frontend
npm install axios
React Component for Fetching Items:
codeimport React, { useState, useEffect } from 'react';
import axios from 'axios';
const App = () => {
const [items, setItems] = useState([]);
const [cart, setCart] = useState([]);
const [total, setTotal] = useState(0);
useEffect(() => {
axios.get('http://localhost:8080/items')
.then(response => setItems(response.data))
.catch(error => console.error('Error fetching items:', error));
}, []);
const addToCart = (item) => {
setCart([...cart, item]);
setTotal(total + item.price);
};
return (
<div>
<h1>Shop</h1>
{items.map((item, index) => (
<div key={index}>
<h3>{item.name}</h3>
<p>Price: ${item.price}</p>
<button onClick={() => addToCart(item)}>Add to Cart</button>
</div>
))}
<h2>Cart</h2>
<ul>
{cart.map((item, index) => (
<li key={index}>
{item.name} - ${item.price}
</li>
))}
</ul>
<h3>Total Bill: ${total}</h3>
</div>
);
};
export default App;
Dockerizing the Application
Dockerfile for Rust Backend:
code# Stage 1: Build the Rust application
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
# Stage 2: Create a minimal image
FROM debian:buster-slim
WORKDIR /app
COPY --from=builder /app/target/release/backend /app/backend
EXPOSE 8080
CMD ["./backend"]
Dockerfile for React Frontend:
code# Stage 1: Build the React application
FROM node:16 as builder
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Serve with NGINX
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker Compose:
codeversion: '3.8'
services:
backend:
build:
context: ./backend
ports:
- "8080:8080"
frontend:
build:
context: ./frontend
ports:
- "3000:80"
depends_on:
- backend
Explanation
- Rust Backend:
- The backend serves an API endpoint (
/items
) using the Actix-Web framework. It returns a JSON response containing item data. - Rust’s performance and reliability make it a perfect choice for the backend.
- The backend serves an API endpoint (
- React Frontend:
- The React app fetches data from the Rust API and displays it dynamically. Users can add items to the cart, and the total price is updated in real time.
- Dockerization:
- Docker simplifies deployment by packaging the backend and frontend into isolated containers.
- A
docker-compose.yml
file orchestrates the services, ensuring they communicate seamlessly.
- Development Workflow:
- Developers can run
docker-compose up
to start the entire application stack locally. - The application runs on
localhost:3000
for the frontend andlocalhost:8080
for the backend.
- Developers can run
Conclusion
Combining Rust, React, and Docker creates a powerful and efficient full-stack application. Rust’s speed and memory safety make it ideal for the backend, while React’s component-based architecture ensures a dynamic frontend. Docker ties everything together for easy deployment and scaling.