- Overview
- Getting Started
- Running the App
- Main Application Features
- Project Structure Overview
- Core Third-Party Packages
- References
This is a Flutter app project to display NASA's astronomy picture of the day.
This project is a fully functional example, focussed on showing astronomy-related images by making http requests to NASA's public APIs.
You can take the code in this project and experiment with it.
git clone https://github.com/dartoos-dev/astronomy_picture_of_the_day.git
cd astronomy_picrture_of_the_day
As it is a Flutter project, you can run it on different platforms — Android, IoS, Web, etc. But before running the application, you need to know which devices are connected to your computer; you can achieve this by listing all devices with the following terminal command:
flutter devices
The above command will display a list similar to:
For example, to run the app on one of the listed devices in debug mode:
flutter run -d RQCW70
flutter run -d 257E76
flutter run -d chrome
- List of astronomy pictures of the day retrieved from NASA's public API.
- Detail page of selected picture.
- Pull-to-refresh capability.
- Pagination.
- Automatically retries http requests when the device connection is intermittent or the server is offline at the time of the request — it uses an exponential backoff algorithm to retry the failed requests.
- It still works when offline.
- Clean Architecture
lib
└───features
│ └───feature1
│ │ └───sub_feature
│ │ └───data
│ │ └───domain
│ │ └───external
│ │ └───presenter
│ └───feature2
│ │ └───sub_feature
│ │ └───data
│ │ └───domain
│ │ └───external
│ │ └───presenter
└───shared
│ app_module.dart
│ app_widget.dart
│ main.dart
In regard to packages or modules, this project uses the "package-by-feature" approach rather than the more usual "package-by-layer". The former uses packages to reflect the feature set; it places all items related to a single feature into a single directory whose name corresponds to important, high-level aspects of the problem domain.
It is important to note that package-by-feature style still honors the idea of separating layers, but that separation is implemented using separate classes.
- easy and logical code navigation — all items needed for a task are usually in the same directory.
- emphasis on core services rather than implementation details.
- scope minimization (package-private as default, not public as in package-by-layer).
- low coupling between modules.
- scalability: the number of classes remains limited to the items related to a specific feature.
- poor overview of all classes that belong to a feature.
- complex, hard to understand, and easy to break code as impact of a change is hard to grasp.
- leads to central classes containing all methods for every use case. Over time, those methods get bigger (with extra parameters) to fulfill more use cases.
- dartz: functional library.
- dio: http client library.
- flutter_modular: dependency injection and routing.
- lint: stricter static analysis rules.
- localization: simplifies in-app translation.
- mocktail: mock framework for unit testing purposes.