https://github.com/rjxby/modern-tenon
The ModernTenon API stands as a comprehensive reference implementation, showcasing the application of industry-standard practices and architectural patterns in backend development using .NET technologies.
https://github.com/rjxby/modern-tenon
api docker dotnet entity-framework-core integration-testing sqlite unit-testing
Last synced: 2 months ago
JSON representation
The ModernTenon API stands as a comprehensive reference implementation, showcasing the application of industry-standard practices and architectural patterns in backend development using .NET technologies.
- Host: GitHub
- URL: https://github.com/rjxby/modern-tenon
- Owner: rjxby
- License: mit
- Created: 2024-04-15T22:23:28.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2026-04-03T00:03:09.000Z (2 months ago)
- Last Synced: 2026-04-03T10:38:23.727Z (2 months ago)
- Topics: api, docker, dotnet, entity-framework-core, integration-testing, sqlite, unit-testing
- Language: C#
- Homepage:
- Size: 35.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ModernTenon API
ModernTenon is a small products API built with ASP.NET Core minimal APIs, Entity Framework Core, and SQLite. The current codebase targets the latest project upgrades in this repository: `.NET 10` and `EF Core 10`.
## What Is In The Repo
- `Backend/Api/Host`: HTTP host, endpoint mapping, Swagger, and app configuration.
- `Backend/Api/Services`: application service layer and mapping between API/domain models.
- `Backend/Api/Repositories`: EF Core data access, SQLite context, and migrations.
- `Backend/Tests`: unit tests and integration tests.
## Current Stack
- .NET 10
- ASP.NET Core minimal APIs
- Entity Framework Core 10
- SQLite
- Swagger / Swashbuckle
- xUnit, FluentAssertions, Moq, Bogus
Central package versions are managed in [`Backend/Directory.Packages.props`](/Backend/Directory.Packages.props).
## API Surface
The API exposes product endpoints under `/api/products`.
- `GET /api/products?page=1&limit=10`: list products with pagination metadata.
- `GET /api/products/{id}`: fetch a single product.
- `POST /api/products`: create a product.
- `PUT /api/products/{id}`: update a product.
### Request Models
`POST /api/products`
```json
{
"name": "Keyboard"
}
```
`PUT /api/products/{id}`
```json
{
"name": "Mechanical Keyboard",
"price": 149.99
}
```
Validation currently requires:
- `name` to be present and at least 3 characters long.
- `price` on update to be present and greater than `0`.
## Local Development
### Prerequisites
- .NET 10 SDK
- `dotnet-ef` CLI tool if you want to apply or create migrations through the `Makefile`
### Run The API
From the repository root:
```bash
dotnet restore Backend/ModernTenon.sln
dotnet run --project Backend/Api/Host
```
The API applies pending EF Core migrations automatically during startup. For local `dotnet run`, the default SQLite file is configured in [`Backend/Api/Host/appsettings.json`](/Backend/Api/Host/appsettings.json):
```json
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=Backend/Api/Host/data/modern-tenon.db"
}
}
```
This is now explicit: the configured path is used as-is. Override it in any environment with `ConnectionStrings__DefaultConnection`.
Default local URLs from [`launchSettings.json`](/Backend/Api/Host/Properties/launchSettings.json):
- `http://localhost:5108`
- `https://localhost:7001`
Swagger UI is enabled in Development at:
- `https://localhost:7001/swagger`
- `http://localhost:5108/swagger`
## Makefile Shortcuts
The repository includes a [`Makefile`](/Makefile) with common EF Core commands:
```bash
make add-migration name=YourMigrationName
make remove-migration
make apply-migrations
```
For a one-command container run with persisted SQLite storage:
```bash
make dev-run
```
That builds the image with Podman and runs it with a named volume mounted at `/data`. The image sets `ConnectionStrings__DefaultConnection=Data Source=/data/modern-tenon.db`, so the container owns the DB path and applies migrations on startup. The same contract works with Docker:
```bash
docker build -t modern-tenon-api-dev -f Backend/Api/Host/Dockerfile ./Backend
docker run --mount type=volume,src=moderntenon-data,dst=/data -p 8080:8080 modern-tenon-api-dev
```
## Tests
Run all tests:
```bash
dotnet test Backend/ModernTenon.sln
```
The integration test suite boots the API through `WebApplicationFactory` and replaces the configured database with an in-memory SQLite database.
For a quick end-to-end smoke test against the real HTTP server:
```bash
make smoke-test
```
To target a specific host:
```bash
make smoke-test HOST=http://127.0.0.1:8080
```
`make smoke-test` assumes your API is already running and only sends HTTP requests. It does not start the app or touch the database.
That script will:
- call `GET /api/products`
- create a product with `POST /api/products`
- fetch it with `GET /api/products/{id}`
- update it with `PUT /api/products/{id}`