Skip to content

itsbudiart/net-service-product

Repository files navigation

ProductService

Simple ASP.NET Core Web API for managing products using a Clean Architecture approach.

Tech Stack

  • .NET 8
  • ASP.NET Core Web API
  • Dapper
  • PostgreSQL
  • xUnit
  • Docker

Project Structure

ProductService.sln
src/
  ProductService.API/
    Controllers/
    HealthChecks/
    Program.cs
    ProductService.API.csproj
  ProductService.Application/
    Interfaces/
    Services/
    ProductService.Application.csproj
  ProductService.Domain/
    Entities/
    ProductService.Domain.csproj
  ProductService.Infrastructure/
    Repositories/
    ProductService.Infrastructure.csproj
tests/
  ProductService.Application.Tests/
Dockerfile
docker-compose.yml

Architecture Overview

This project is split into 4 layers:

  • ProductService.Domain Contains the core application entity, such as Product.
  • ProductService.Application Contains business logic and abstractions, such as IProductRepository and ProductService.
  • ProductService.Infrastructure Contains the PostgreSQL data access implementation using Dapper.
  • ProductService.API Contains controllers, health checks, dependency injection, and application startup.

Request flow:

  1. The request enters a controller in the API layer.
  2. The controller calls a service in the Application layer.
  3. The service uses a repository interface instead of a direct implementation.
  4. The actual repository implementation lives in the Infrastructure layer.
  5. Core entities remain in the Domain layer.

Features

  • CRUD product
  • Health check endpoint
  • Docker support
  • Structured logging with Serilog
  • Elasticsearch log shipping
  • Elastic APM tracing
  • Unit tests for the application layer

API Endpoints

Health Check

  • GET /health

Products

  • GET /api/products
  • GET /api/products/{id}
  • POST /api/products
  • PUT /api/products/{id}
  • DELETE /api/products/{id}

Example Request Body

For POST /api/products or PUT /api/products/{id}:

{
  "name": "ASUS Laptop",
  "description": "Laptop for development work",
  "price": 15000000,
  "stock": 10
}

Running Locally

Make sure .NET 8 SDK is installed.

dotnet restore ProductService.sln
dotnet build ProductService.sln
dotnet run --project src/ProductService.API/ProductService.API.csproj

The default development URL usually follows launchSettings.json. If you want to set it explicitly:

dotnet run --project src/ProductService.API/ProductService.API.csproj --urls http://localhost:8080

Database Configuration

The connection string is read from the ConnectionStrings:Postgres key.

Example format:

Host=localhost;Port=5432;Database=productdb;Username=postgres;Password=postgres

Configuration files:

  • src/ProductService.API/appsettings.json
  • src/ProductService.API/appsettings.Development.json

Running With Docker

Build the API image:

docker build -t product-service .

Run with compose:

docker compose up --build

Notes:

  • docker-compose.yml only runs the API service.
  • The API still uses a PostgreSQL instance that is assumed to already exist on the external Docker network local_network.
  • The container connection string is provided through the ConnectionStrings__Postgres environment variable in docker-compose.yml.
  • The Elasticsearch sink target is provided through Serilog__WriteTo__1__Args__nodes__0.
  • The Elastic APM Server endpoint is provided through ElasticApm__ServerUrl.

Logging

The API uses Serilog for structured logging.

  • Request logs are written through UseSerilogRequestLogging().
  • Application and repository logs are written through injected ILogger<T>.
  • Logs are sent to both the console and Elasticsearch.
  • API request duration is emitted in the request log event.
  • Database execution duration is emitted in repository log events.

Default Elasticsearch endpoint:

http://localhost:9200

Important log fields:

  • TransactionId
  • Operation
  • Layer
  • TraceId
  • SpanId
  • ApiResponseTimeMs
  • DurationMs
  • DbSystem
  • DbOperation
  • Table

Elastic APM

The API is instrumented with the Elastic APM .NET agent.

  • APM Server default endpoint: http://localhost:8200
  • Service name: product-service-api
  • Main configuration key: ElasticApm

Docker environment variables:

  • ELASTICSEARCH_URL
  • ELASTIC_APM_SERVER_URL

Request correlation:

  • Response header: X-Transaction-Id
  • Log field: TransactionId
  • If X-Transaction-Id is provided by the client, the API reuses it.
  • If it is not provided, the API generates a random 7-digit value per request.

Running Tests

dotnet test ProductService.sln

The current tests focus on the application layer:

  • returning all products
  • returning a product by id
  • assigning Id and CreatedAt during product creation
  • passing updated product data to the repository
  • passing the product id to the repository for deletion

Postman Collection

The Postman collection is available at:

  • ProductService.postman_collection.json

Import that file into Postman and update the baseUrl variable if needed.

Notes

  • The health check endpoint is available at /health.
  • Swagger is enabled when the environment is Development.
  • The repository uses Dapper with direct SQL queries against the products table.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors