A RESTful API built with FastAPI for managing employee data with full CRUD operations, filtering capabilities, and soft delete functionality.
- Create, Read, Update, and Delete employee records
- Soft delete (mark as inactive) and hard delete options
- Filter employees by department and active status
- Pagination support
- Email validation
- PostgreSQL database with SQLAlchemy ORM
- Docker containerization
- Interactive API documentation (Swagger UI & ReDoc)
- Framework: FastAPI 0.121.2
- Database: PostgreSQL 15
- ORM: SQLAlchemy 2.0.44
- Migration: Alembic 1.17.2
- Container: Docker & Docker Compose
- Python: 3.13+
employee-api/
app/
__init__.py
main.py # FastAPI app & endpoints
models.py # SQLAlchemy models
schemas.py # Pydantic schemas
crud.py # Database operations
database.py # Database configuration
docker-compose.yml
Dockerfile
pyproject.toml
.env
README.md- Clone the repository and navigate to the project directory
- Start the services:
docker-compose up --build- Access the API
- API: http://localhost:8000
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Install dependencies with uv:
uv sync- Set up environment variables in
.env:
DATABASE_URL=postgresql://employee_user:employee_pass@localhost:5432/employee_db
POSTGRES_USER=employee_user
POSTGRES_PASSWORD=employee_pass
POSTGRES_DB=employee_db- Start PostgreSQL (if using Docker):
docker-compose up db- Run the application:
uv run uvicorn app.main:app --reload| Method | Endpoint | Description |
|---|---|---|
| POST | /employees/ |
Create a new employee |
| GET | /employees/ |
Get all employees (with filters) |
| GET | /employees/{id} |
Get employee by ID |
| PUT | /employees/{id} |
Update employee |
| DELETE | /employees/{id} |
Soft delete employee |
| DELETE | /employees/{id}/permanent |
Permanently delete employee |
| Method | Endpoint | Description |
|---|---|---|
| GET | / |
Welcome message |
| GET | /health |
Health check |
| GET | /docs |
Swagger UI documentation |
| GET | /redoc |
ReDoc documentation |
{
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"department": "string",
"position": "string",
"salary": 0.0,
"is_active": true
}skip: Number of records to skip (default: 0)limit: Maximum records to return (default: 100, max: 100)department: Filter by department nameis_active: Filter by active status (true/false)
Example:
GET /employees/?department=Engineering&is_active=true&skip=0&limit=10curl -X POST "http://localhost:8000/employees/" \
-H "Content-Type: application/json" \
-d '{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@company.com",
"department": "Engineering",
"position": "Senior Developer",
"salary": 95000.00,
"is_active": true
}'curl "http://localhost:8000/employees/"curl "http://localhost:8000/employees/?department=Engineering"curl -X PUT "http://localhost:8000/employees/1" \
-H "Content-Type: application/json" \
-d '{
"salary": 105000.00,
"position": "Lead Developer"
}'curl -X DELETE "http://localhost:8000/employees/1"Using Alembic for database migrations:
# Create a new migration
uv run alembic revision --autogenerate -m "description"
# Apply migrations
uv run alembic upgrade head
# Rollback migration
uv run alembic downgrade -1DATABASE_URL: PostgreSQL connection stringPOSTGRES_USER: Database userPOSTGRES_PASSWORD: Database passwordPOSTGRES_DB: Database name
# Start all services
docker-compose up
# Start in detached mode
docker-compose up -d
# Stop services
docker-compose down
# View logs
docker-compose logs -f
# Rebuild containers
docker-compose up --buildInstall development dependencies:
uv syncRun the development server with auto-reload:
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000