Flask RESTful API starter template ready to deploy on Railway (railway.app), with a clean folder structure, SOLID design, and a standardized response shape.
- Clean folder structure using an application factory (
app/). - Standardized API response:
{
"data": {},
"status": 200,
"message": "Success"
}- Built-in endpoints:
GET /– root application info.GET /health– simple health check.GET /status– service status & uptime.
- Docker-ready: includes
Dockerfile,.dockerignore. - Railway-ready: reads
PORTfrom environment variables.
.
├── app
│ ├── __init__.py # Application factory & wiring dependency
│ ├── config.py # Configuration (dev/production)
│ ├── core
│ │ └── response.py # ResponseFactory & ApiResponse (SOLID)
│ └── routes.py # Routes / controllers
├── main.py # Local entry point (development)
├── requirements.txt # Python dependencies
├── Dockerfile # Image definition for Railway
├── .env # Local config (do not commit)
├── .env.example # Example env file
├── .gitignore
├── .dockerignore
├── LICENSE
└── README.md
- Create a virtual environment
python -m venv .venv
source .venv/bin/activate # Linux / macOS
# or
.venv\Scripts\activate # Windows- Install dependencies
pip install -r requirements.txt- Create a
.envfile
cp .env.example .envAdjust values if needed.
- Run the server (development)
python main.pyThe app will run at http://localhost:8000 (based on PORT in .env).
- GET
/- Description: root endpoint that returns basic app info and environment.
- Example response:
{
"data": {
"app": "Flask Railway API",
"environment": "development"
},
"status": 200,
"message": "Root endpoint"
}- GET
/health
{
"data": {
"healthy": true
},
"status": 200,
"message": "Health check OK"
}- GET
/status
{
"data": {
"uptime_seconds": 12,
"environment": "development"
},
"status": 200,
"message": "Service status"
}- Push this project to a Git repository (GitHub/GitLab).
- In Railway:
- Create New Project → Deploy from Repo.
- Select this repository.
- Railway will detect the
Dockerfile.
- Set minimum Environment Variables:
ENVIRONMENT=production- (optional)
APP_NAME,PORT(Railway typically providesPORTautomatically).
The Dockerfile runs gunicorn:
gunicorn -w 3 -b 0.0.0.0:8000 main:appRailway provides the port via the PORT environment variable, while this image exposes 8000. If you want to strictly bind to Railway's PORT, update the CMD in the Dockerfile to read PORT dynamically.
- Single Responsibility:
ResponseFactoryonly handles response shape.routes.pydefines endpoints and uses injected dependencies.config.pyhandles configuration.
- Open/Closed:
- To add new response types (e.g., pagination), add a new method in
ResponseFactorywithout changing existing ones.
- To add new response types (e.g., pagination), add a new method in
- Simple Dependency Injection:
ResponseFactoryis injected into the app (app.response_factory) and accessed viacurrent_appinside endpoints.
You can add more blueprints/routes and keep the response shape consistent by using ResponseFactory.