Integrating FastAPI and React: Building a Full-Stack Application
In today's world of web development, the ability to seamlessly integrate frontend and backend technologies is a must. In this post, we're going to explore building a full-stack application using FastAPI and React, two popular and powerful technologies that are gaining ground in the developer community.
Introduction to the Tools
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. It is easy to use and encourages good software design practices, such as the use of dependency injection. FastAPI's key features include automatic interactive API documentation, based on OpenAPI and JSON Schema, and its incredible performance.
React is a JavaScript library for building user interfaces, maintained by Facebook and a community of individual developers and companies. It allows you to create reusable UI components and makes it painless to create interactive UIs. React’s component-based architecture greatly simplifies the development of complex user interfaces.
Setting Up Your FastAPI Backend
Firstly, we'll need to set up our FastAPI backend. Let's create a simple API for a hypothetical to-do list application.
Install FastAPI and an ASGI server, such as uvicorn (this is what I used in production for govtrades.io):
pip install fastapi uvicorn
Now, create a new file, main.py, and add the following code:
- Note: it is recommended to set up a virtual environment such as virtualenv or miniconda.
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional, List
app = FastAPI()
class Todo(BaseModel):
name: str
due_date: str
description: Optional[str] = None
todos = []
@app.get("/todos")
async def get_todos():
return todos
@app.post("/todos")
async def add_todo(todo: Todo):
todos.append(todo.dict())
return todos[-1]
@app.delete("/todos/{todo_id}")
async def delete_todo(todo_id: int):
todos.pop(todo_id)
return {}
This code creates a FastAPI application and sets up three endpoints: one for getting all to-dos, one for adding a new to-do, and one for deleting a to-do. Each to-do is represented as a Python dictionary with a name, due_date, and optional description.
You can run your FastAPI server using the following command:
uvicorn main:app --reload
Setting Up Your React Frontend
Now that our backend is set up, let's turn our attention to the frontend.
We'll be using Create React App to set up our React project. Install it globally using the following command:
npx create-react-app todo-app
Then, navigate into your new project directory and install axios, a promise-based HTTP client for the browser and node.js:
cd todo-app
npm install axios
Create a new file, App.js, and add the following code:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [todos, setTodos] = useState([]);
useEffect(() => {
axios.get('http://localhost:8000/todos')
.then(response => {
setTodos(response.data);
});
}, []);
// any other code you want to add will go here
return (
<div className="App">
{/* All the Todos... */}
</div>
);
}
export default App;
This code creates a React component that fetches the to-dos from our FastAPI backend when the component is first rendered. We're using the useState and useEffect hooks here, which are built-in React hooks that allow us to add state and side effects to our function components.
Integrating the Frontend and Backend
Now we have our separate frontend and backend set up, it's time to integrate them. Let's add functionality to our React app to add and delete to-dos.
Here's how our App.js should look after adding the new functionality:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState({name: "", due_date: "", description: ""});
useEffect(() => {
fetchTodos();
}, []);
const fetchTodos = () => {
axios.get('http://localhost:8000/todos')
.then(response => {
setTodos(response.data);
});
}
const addTodo = () => {
axios.post('http://localhost:8000/todos', newTodo)
.then(() => {
fetchTodos();
setNewTodo({name: "", due_date: "", description: ""});
});
}
const deleteTodo = (todoId) => {
axios.delete(`http://localhost:8000/todos/${todoId}`)
.then(() => {
fetchTodos();
});
}
return (
<div className="App">
{/* Display form to add new todo */}
<div>
<h2>Add a New Todo</h2>
<input
type="text"
placeholder="Name"
value={newTodo.name}
onChange={e => setNewTodo({ ...newTodo, name: e.target.value })}
/>
<input
type="text"
placeholder="Due Date"
value={newTodo.due_date}
onChange={e => setNewTodo({ ...newTodo, due_date: e.target.value })}
/>
<textarea
placeholder="Description"
value={newTodo.description}
onChange={e => setNewTodo({ ...newTodo, description: e.target.value })}
/>
<button onClick={addTodo}>Add Todo</button>
</div>
{/* Display list of todos */}
<div>
<h2>Your Todos</h2>
{todos.map((todo, index) => (
<div key={index}>
<h3>{todo.name}</h3>
<p>Due: {todo.due_date}</p>
<p>{todo.description}</p>
<button onClick={() => deleteTodo(index)}>Delete</button>
</div>
))}
</div>
</div>
);
}
export default App;
This code adds functions to add and delete to-dos, which are called when the corresponding buttons are clicked. It also includes a form to add new to-dos, and it displays the list of current to-dos. Each to-do is displayed with a "Delete" button that calls deleteTodo() when clicked.
You can run your React app using the following command:
npm start
or if you decided to use a framework such as Next.js
npm run dev
Now, navigate to http://localhost:3000 in your web browser, and you should see your React app. You can add and delete to-dos, and the changes will be reflected in your FastAPI backend.
Wrapping Up
There you have it: a simple full-stack application using FastAPI and React. There's certainly more we could do here, like adding the ability to edit existing to-dos, improving the UI, or adding user authentication, but this gives you a good starting point.
The beauty of this stack lies in its simplicity and flexibility. FastAPI's ease of use and powerful features make it a joy to build APIs with, and React's component-based architecture allows for highly complex, interactive UIs. Together, they make for a robust and scalable full-stack application.
I hope this guide helps you understand how you can integrate FastAPI and React to build powerful full-stack applications.
- Note: Please ensure to properly handle errors and edge cases in production applications. This guide is meant to be a simple demonstration of how FastAPI and React can work together.