Skip to content

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

Notifications You must be signed in to change notification settings

Gramli/WeatherApi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Clean Architecture WeatherApi

.NET Build and Test Codacy Badge Codacy Badge

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 from Weatherbit via RapidAPI. It also allows users to add favorite locations to an in memory database and retrieve weather data for those stored locations.

Menu

Prerequisites

  • .NET SDK 9.0.x

Installation

To install the project using Git Bash:

  1. Clone the repository:
    git clone https://github.com/Gramli/WeatherApi.git
  2. Navigate to the project directory:
    cd WeatherApi/src
  3. Install the backend dependencies:
    dotnet restore

Get Started

  1. Register on RapidAPI
  2. Subscribe Weatherbit (its for free) and go to Endpoints tab
  3. 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"
  }
  1. Run Weather.API

Try it in SwaggerUI

SwaggerUI

Try it using .http file (VS2022)

  • Go to Tests/Debug folder and open debug-tests.http file (in VS2022)
  • Send request

Motivation

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.

Architecture

This project follows Clean 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 use MediatR. Instead, each endpoint has its own request and handler. The solution follows the CQRS 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 the Result pattern (using the FluentResuls 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 is testing. When writing tests, we aim for optimal 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 write system tests. These tests typically call API endpoints in a specific order defined by business requirements and check the expected results. The solution contains simple System Tests, which call the exposed endpoints and validate the response.

Clean Architecture Layers

  • WeatherAPI This 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.Infrastructure This 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.Core This 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.Domain Contains 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.

Horizontal Diagram (references)

Project Clean Architecture Diagram

Pros and Cons

Technologies

About

An example of REST API for handling weather data using minimal API and Clean Architecture with various design patterns. ASP.NET Core 9.0

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published