ApiDog Flutter Demo is a sample Flutter app built using Clean Architecture principles to demonstrate how to consume a REST API using ApiDog in a modular, reusable, and scalable way.
⚙️ Built with
Provider
,flutter_dotenv
, and a layered architecture:core
,domain
,data
, andpresentation
.
- ✅ Fetch a single
Pet
- ✅ Fetch a list of
Pet
s - ✅ Environment management via
.env
files - ✅ Proper separation of concerns through Clean Architecture
- ✅ Centralized error handling using
Failure
andException
classes - ✅ Generic API response handling with
ApiResponse<T>
lib/
├── core/
│ └── error/ → Error and exception handling
├── data/
│ ├── datasources/ → API services (http requests)
│ └── repositories/ → Repository implementations
├── domain/
│ ├── entities/ → Models and generic API responses
│ ├── repositories/ → Abstract repository interfaces
│ └── usecases/ → Reusable business logic
├── presentation/
│ ├── providers/ → State management
│ └── screens/ → UI layer (main screen)
└── main.dart → App entry point and config
This project uses flutter_dotenv
to manage multiple environments such as development, staging, and production.
your_project/
└── environment/
├── .env.dev
├── .env.local
└── .env.prod
Example .env.dev
:
API_URL=https://dev.api.apidog.com
Example .env.prod
:
API_URL=https://api.apidog.com
By default, main.dart
loads the .env.local
file:
await dotenv.load(fileName: 'environment/.env.local');
final apiUrl = dotenv.env['API_URL']!;
💡 You can change which
.env
file to load based on the environment or flavor you want to run.
If you want to mock API responses using local static JSON files, such as:
assets/mock/pet_response.json
→ for a single pet detailassets/mock/pet_list_response.json
→ for the list of pets
you can toggle this behavior using a JSON_DATA
variable in your .env
files.
ℹ️ Behavior based on
JSON_DATA
value
- When
JSON_DATA=true
, the app will load data from local static JSON files instead of making real API calls.- When
JSON_DATA=false
, the app will use the live API defined in theAPI_URL
variable.
In the pet_item.dart
file, each PetItem
can be configured with a standalone
boolean flag:
- When
standalone = true
, the Pet Detail page will fetch data directly from ApiDog using the pet ID. - When
standalone = false
, the Pet Detail page will receive the fullPet
object via props, and no extra fetch is performed.
✅ This allows you to decide if the pet should be fetched or passed via widget prop.
# .env.local, .env.dev, or .env.prod
JSON_DATA=false
API_URL=http://127.0.0.1:3658/<apidog_path>
---
## 🧪 How to Run
### ✅ Start the app
1. Make sure your `.env` files are created inside the `environment/` folder
2. Make sure to have API_URL variable from apidog
3. Make sure to have JSON_DATA variable setted to false/true
4. Run the app:
```bash
flutter pub get
flutter run
or for vs_code like, launch.json
{
"version": "1.0.0",
"configurations": [
{
"name": "Local",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"args": [
"--dart-define=ENV=local"
]
},
]
}
You can easily extend this project by adding more models and endpoints:
- Create a new
Entity
class - Add a new
Service
andRepositoryImpl
- Inject a new
FetchApiData<T>
use case into your Provider
Home Screen | Detail |
---|---|
![]() |
![]() |
http
– for HTTP requestsprovider
– for state managementflutter_dotenv
– for environment variable handlingjson_annotation
– for JSON annotationjson_serializable
– for JSON serialization
Have an idea or a bug fix? Feel free to open a pull request! ❤️
MIT License © 2025 Gionata Stante / Open Reply