REST APIs stand for Representational State Transfer, and they are the backbone of modern software...
FastAPI + Bruno: A Better Way to Build and Test APIs
FastAPI helps you build APIs faster with automatic OpenAPI documentation, built-in Swagger and ReDoc support, and a clean Python developer experience. Bruno makes testing easier by importing your OpenAPI spec into a local-first, Git-friendly API collection
Table of Contents
Why FastAPI + Bruno?
API development usually involves three repeating tasks: building endpoints, maintaining documentation, and testing requests. In many teams, those pieces drift apart quickly. The backend changes, the docs become outdated, and test collections no longer reflect the real API.
FastAPI and Bruno work especially well together because FastAPI automatically generates the OpenAPI specification from your code, and Bruno can import that spec directly into a local, Git-based collection. That means less duplication, less manual effort, and a much smoother workflow from development to testing.
Traditional vs FastAPI Workflow
Traditional API Development
FastAPI + Bruno Workflow
Why FastAPI is Changing Backend Development
Faster development with less boilerplate
FastAPI uses Python type hints and Pydantic models to handle validation, serialization, and schema generation automatically. Instead of writing the same information multiple times for models, docs, and validation, you define it once in Python and FastAPI takes care of the rest.
Built-in interactive documentation
One of FastAPI’s biggest advantages is that it ships with automatic API documentation out of the box.
/docsgives you Swagger UI/redocgives you ReDoc/openapi.jsongives you the OpenAPI specification
That means you can build the API and instantly browse, test, and share the documentation without manually maintaining a separate spec file.
Easy to learn and productive quickly
FastAPI feels natural for Python developers. The syntax is clean, readable, and intuitive, which makes it approachable for both beginners and experienced backend engineers.
Strong community support
FastAPI has a strong ecosystem, active community support, great documentation, and broad adoption in startups and production systems. It fits naturally into modern Python application stacks.
Project Setup
Create a virtual environment and install the packages needed for FastAPI, Uvicorn, and MongoDB integration.
python -m venv venv
source venv/bin/activate
pip install fastapi uvicorn pymongo
MongoDB Connection
Start by setting up the FastAPI app, MongoDB connection, and the Todo model. This is the base of the CRUD API.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from pymongo import MongoClient
from bson import ObjectId
app = FastAPI(
title="Todo API",
description="Simple CRUD API with FastAPI and MongoDB",
version="1.0.0"
)
client = MongoClient("mongodb://localhost:27017")
db = client["testdb"]
collection = db["todos"]
class Todo(BaseModel):
title: str
completed: bool = False
Create Endpoint (POST)
The POST endpoint lets you create a new todo item and store it in MongoDB.
@app.post("/todos")
def create_todo(todo: Todo):
result = collection.insert_one(todo.dict())
return {"id": str(result.inserted_id), **todo.dict()}
Read Endpoints (GET)
You can expose one GET endpoint to list all todos and another to fetch a single todo by its ID.
@app.get("/todos")
def get_todos():
todos = []
for t in collection.find():
t["id"] = str(t["_id"])
del t["_id"]
todos.append(t)
return todos
@app.get("/todos/{id}")
def get_todo(id: str):
todo = collection.find_one({"_id": ObjectId(id)})
if not todo:
raise HTTPException(status_code=404, detail="Not found")
todo["id"] = str(todo["_id"])
del todo["_id"]
return todo
Update Endpoint (PUT)
The PUT endpoint updates an existing todo by ID.
@app.put("/todos/{id}")
def update_todo(id: str, todo: Todo):
result = collection.update_one(
{"_id": ObjectId(id)},
{"$set": todo.dict()}
)
if result.matched_count == 0:
raise HTTPException(status_code=404, detail="Not found")
return {"message": "Updated"}
Delete Endpoint (DELETE)
The DELETE endpoint removes a todo from MongoDB.
@app.delete("/todos/{id}")
def delete_todo(id: str):
result = collection.delete_one({"_id": ObjectId(id)})
if result.deleted_count == 0:
raise HTTPException(status_code=404, detail="Not found")
return {"message": "Deleted"}
Run the API
Start the development server with Uvicorn:
uvicorn main:app --reload
Swagger, ReDoc, and OpenAPI
Once the app is running, FastAPI automatically exposes documentation and schema endpoints:
http://localhost:8000/docsfor Swagger UIhttp://localhost:8000/redocfor ReDochttp://localhost:8000/openapi.jsonfor the raw OpenAPI spec
Key benefit: you do not need to manually write Swagger or OpenAPI YAML. FastAPI generates everything from your route definitions and Pydantic models.
Import FastAPI into Bruno
Once your OpenAPI spec is available, Bruno can import it directly and generate a collection for your API endpoints.
- Open Bruno
- Import collection

- Choose the OpenAPI import option and paste -
http://localhost:8000/openapi.json
- Click on the import button.

Bruno will generate requests for your endpoints automatically, which makes testing the API much easier. Instead of creating each request manually, you get a ready-to-use collection based on the same OpenAPI spec generated by FastAPI.
Why Bruno fits so well here
- Local-first workflow
- Git-based collections
- Fast and lightweight
- Easy OpenAPI import
- Simple endpoint testing and CLI support
Because Bruno stores collections locally as files, it is especially useful for developers and teams who want their API test collections version-controlled alongside application code.
bru run --env local
Tip: Bruno recently introduced a feature called OpenAPI Sync, which helps keep your OpenAPI file in sync with your collection. You can read more about it here.
Wrap Up
FastAPI and Bruno create a strong workflow for modern API development. FastAPI speeds up backend development with clean Python code, automatic validation, and built-in interactive docs. Bruno makes testing straightforward by turning your OpenAPI spec into a local, Git-friendly collection you can run and maintain easily.
Together, they reduce duplication across development, documentation, and testing. You spend less time maintaining docs manually and more time shipping useful APIs.
Useful endpoints to remember:
/docsfor Swagger UI/redocfor ReDoc/openapi.jsonfor the OpenAPI specification
Happy building 🚀