- Notifications
You must be signed in to change notification settings - Fork6
An example of REST API for handling weather data using minimal API and Clean Architecture with various design patterns. ASP.NET Core 9.0
License
Gramli/WeatherApi
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This REST API solution demonstrates how to create a clean, modern API (from my point of view) using Clean Architecture, Minimal API, and various design patterns.
The example API allows users to retrieve current and forecasted weather data by location fromWeatherbit viaRapidAPI. It also allows users to add favorite locations to anin memory database and retrieve weather data for those stored locations.
- .NET SDK 9.0.x
To install the project using Git Bash:
- Clone the repository:
git clone https://github.com/Gramli/WeatherApi.git
- Navigate to the project directory:
cd WeatherApi/src
- Install the backend dependencies:
dotnet restore
- Register onRapidAPI
- SubscribeWeatherbit (its for free) and go to Endpoints tab
- In API documentation copy (from Code Snippet)X-RapidAPI-Key,X-RapidAPI-Host and put them to appsettings.json file in WeatherAPI project
"Weatherbit": {"BaseUrl":"https://weatherbit-v1-mashape.p.rapidapi.com","XRapidAPIKey":"value from code snippet","XRapidAPIHost":"value from code snippet" }
- Run Weather.API
- Go to Tests/Debug folder and opendebug-tests.http file (in VS2022)
- Send request
The main motivation for this project is to create a practical example of Minimal API, to explore its benefits and drawbacks, and to build a REST API using Clean Architecture and various design patterns.
This project followsClean Architecture. The application layer is split into the Core and Domain projects, where the Core project holds the business rules, and the Domain project contains the business entities.
Since Minimal API allows injecting handlers into endpoint mapping methods, I decided not to useMediatR. Instead, each endpoint has its own request and handler. The solution follows theCQRS pattern, where handlers are separated into commands and queries. Command handlers handle command requests, while query handlers handle query requests. Additionally, repositories (Repository pattern) are also separated into command and query repositories.
Instead of throwing exceptions, the project uses theResult pattern (using theFluentResuls package). Every handler returns data wrapped in an HttpDataResponse object, which also contains a collection of error messages and an HTTP status code.
Each HTTP status code's response is wrapped in a DataResponse class, which holds the result data and any errors. This approach allows, for example, returning error messages alongside an "OK" status code.
An important aspect of any project istesting. When writing tests, we aim foroptimal code coverage. I believe every project has its own optimal coverage based on its needs. My rule is: cover your code enough to confidently refactor without worrying about functionality changes.
In this solution, each code project has its own unit test project, and each unit test project mirrors the directory structure of its respective code project. This structure helps with organization in larger projects.
To ensure the REST API works as expected for end users, we writesystem tests. These tests typically call API endpoints in a specific order defined by business requirements and check the expected results. The solution contains simpleSystem Tests, which call the exposed endpoints and validate the response.
WeatherAPIThis is the entry point of the application and the top layer, containing:
- Endpoints: Define and expose application routes.
- Middlewares (or Filters): Handle cross-cutting concerns like exception handling and logging.
- API Configuration: Centralized setup for services, routes, and middleware.
Weather.InfrastructureThis layer handles communication with external resources, such as databases, caches, and web services. It includes:
- Repositories Implementation: Provides access to the database.
- External Services Proxies: Proxy classes for obtaining data from external web services.
- ** Weatherbit.Client** - A standalone project dedicated to communication with RapidAPI/Weatherbit.
- Infrastructure-Specific Services: Services required to interact with external libraries and frameworks.
Weather.CoreThis layer contains the application's business logic, including:
- Request Handlers/Managers: Implement business operations and workflows.
- Abstractions: Define interfaces and contracts, including abstractions for the infrastructure layer (e.g., services, repositories) to ensure their usability in the core layer.
Weather.DomainContains shared components that are used across all projects, such as:
- DTOs: Data Transfer Objects for communication between layers.
- General Extensions: Common utilities and extension methods.