Category: python
Introduction to Building Microservices with FastAPI
Published on 22 Aug 2026
Explanation
FastAPI is a modern Python web framework that is well suited for building REST APIs and microservices. A microservice should normally focus on one business responsibility instead of containing the entire application's functionality. For example, an e-commerce system can have separate User, Product, Order, and Payment services. Each service can run independently on a different port and expose its own API endpoints. FastAPI provides automatic API documentation, request validation, type hints, and asynchronous support.
Code:
# Install FastAPI and Uvicorn
# pip install fastapi uvicorn
from fastapi import FastAPI
app = FastAPI(title='Product Service')
@app.get('/products')
def get_products():
return {
'service': 'Product Service',
'products': []
}
# Run the service:
# uvicorn product_service:app --port 8001 --reload
Explanation
A Product Service is responsible only for product-related functionality. It can provide endpoints to create, retrieve, update, and delete products. Keeping product logic inside its own service allows the service to evolve and scale independently. In a real application, the in-memory list would normally be replaced with a database such as PostgreSQL or MySQL.
Code:
from fastapi import FastAPI
app = FastAPI(title='Product Service')
products = [
{'id': 1, 'name': 'Laptop', 'price': 65000},
{'id': 2, 'name': 'Mouse', 'price': 750}
]
@app.get('/products')
def get_products():
return products
@app.get('/products/{product_id}')
def get_product(product_id: int):
for product in products:
if product['id'] == product_id:
return product
return {'message': 'Product not found'}
# Run:
# uvicorn product_service:app --port 8001 --reload
Explanation
The Order Service handles order-related business logic and can run independently from the Product Service. It can expose endpoints for creating and retrieving orders. In a real microservices system, the Order Service may need to communicate with the Product Service to verify product availability and price. This separation keeps each service focused on its own business responsibility.
Code:
from fastapi import FastAPI
app = FastAPI(title='Order Service')
orders = []
@app.post('/orders')
def create_order(product_id: int, quantity: int):
order = {
'id': len(orders) + 1,
'product_id': product_id,
'quantity': quantity
}
orders.append(order)
return order
@app.get('/orders')
def get_orders():
return orders
# Run:
# uvicorn order_service:app --port 8002 --reload
Explanation
Microservices communicate with each other through network protocols. REST APIs over HTTP are one of the most common approaches. Python's httpx library can be used to make asynchronous HTTP requests between FastAPI services. For example, the Order Service can call the Product Service to retrieve product information before creating an order. In production applications, service communication should include appropriate timeouts, error handling, authentication, retries, and service discovery.
Code:
from fastapi import FastAPI, HTTPException
import httpx
app = FastAPI(title='Order Service')
PRODUCT_SERVICE_URL = 'http://localhost:8001'
@app.get('/orders/product/{product_id}')
async def get_product_for_order(product_id: int):
try:
async with httpx.AsyncClient() as client:
response = await client.get(
f'{PRODUCT_SERVICE_URL}/products/{product_id}',
timeout=5.0
)
if response.status_code != 200:
raise HTTPException(
status_code=404,
detail='Product not found'
)
return response.json()
except httpx.RequestError:
raise HTTPException(
status_code=503,
detail='Product Service unavailable'
)
Explanation
A microservices project should keep each service independently organized. Each service can have its own main application, models, routes, services, database layer, tests, and dependency configuration. A larger system can contain separate directories for user-service, product-service, order-service, and payment-service. Each service can have its own virtual environment or dependency configuration and can later be packaged as a separate Docker container. This structure makes development, testing, deployment, and scaling easier.
Code:
microservices-project/
│
├── user-service/
│ ├── app/
│ │ ├── main.py
│ │ ├── models.py
│ │ ├── routes.py
│ │ └── services.py
│ ├── tests/
│ └── requirements.txt
│
├── product-service/
│ ├── app/
│ │ ├── main.py
│ │ ├── models.py
│ │ ├── routes.py
│ │ └── services.py
│ ├── tests/
│ └── requirements.txt
│
├── order-service/
│ ├── app/
│ │ ├── main.py
│ │ ├── models.py
│ │ ├── routes.py
│ │ └── services.py
│ ├── tests/
│ └── requirements.txt
│
└── payment-service/
├── app/
│ ├── main.py
│ ├── models.py
│ ├── routes.py
│ └── services.py
├── tests/
└── requirements.txt