PaletteCoreAPI is an authenticated ASP.NET Core REST API for a palette-oriented social platform. It models users, profiles, posts, colours, tags, comments, favourites, following relationships, and API-key records in SQL Server.
- .NET 10 and ASP.NET Core controllers
- Entity Framework Core with SQL Server and a committed initial migration
- JWT bearer authentication with a secure fallback policy
- role- or scope-based protection for user and API-key administration
- validated request and response DTOs that prevent entity over-posting
- password hashing with ASP.NET Core Identity's
PasswordHasher - API keys returned once on creation and omitted from later reads
- OpenAPI/Swagger documentation, Problem Details, and a public health endpoint
- integration tests with an in-memory database
- GitHub Actions build and test workflow
| Area | Technology |
|---|---|
| Language | C# |
| Runtime | .NET 10 |
| Web framework | ASP.NET Core Web API |
| Data access | Entity Framework Core 10 |
| Database | Microsoft SQL Server |
| Authentication | JWT bearer / OpenID Connect authority |
| API documentation | Swashbuckle OpenAPI and Swagger UI |
| Testing | xUnit, WebApplicationFactory, EF Core InMemory |
| Automation | GitHub Actions |
The API uses a focused controller-to-database design. Controllers accept validated contracts, map them to the existing domain entities, and use PaletteContext for persistence. Authentication is applied globally; only /health is anonymous.
flowchart LR
Client["HTTP client"] --> Auth["JWT bearer authentication"]
Auth --> Controllers["API controllers"]
Controllers --> DTOs["Validated request/response DTOs"]
Controllers --> Context["PaletteContext"]
Context --> EF["Entity Framework Core"]
EF --> SQL[("SQL Server")]
Swagger["Swagger UI"] -. documents .-> Controllers
Health["/health"] --> Checks["Health checks"]
sequenceDiagram
participant Client
participant Auth as JWT middleware
participant Posts as PostsController
participant DB as PaletteContext
Client->>Auth: GET /api/Posts/{id} + bearer token
Auth->>Posts: Authenticated request
Posts->>DB: Read post without tracking
alt Post exists
DB-->>Posts: Posts entity
Posts-->>Client: 200 OK + PostDto
else Post is missing
DB-->>Posts: null
Posts-->>Client: 404 Not Found
end
erDiagram
USERS ||--o{ APIKEYS : owns
USERS ||--o{ POSTS : publishes
USERS ||--o{ USER_PROFILE : has
USERS ||--o{ COMMENTS : writes
POSTS ||--o{ COMMENTS : receives
USERS ||--o{ FAVOURITES : creates
POSTS ||--o{ FAVOURITES : receives
USERS ||--o{ FOLLOWINGS : follows
POSTS ||--o{ POST_COLORS : contains
POSTS ||--o{ POST_TAGS : categorised_by
TAGS ||--o{ POST_TAGS : assigned_through
All domain routes require an authenticated user.
| Resource | Base route | Operations |
|---|---|---|
| Posts | /api/Posts |
GET, GET by ID, POST, PUT, DELETE |
| Post colours | /api/PostColors |
GET, GET by ID, POST, PUT, DELETE |
| Tags | /api/Tags |
GET, GET by ID, POST, PUT, DELETE |
| Post tags | /api/PostTags |
GET, GET by ID, POST, PUT, DELETE |
| Comments | /api/Comments |
GET, GET by ID, POST, PUT, DELETE |
| Favourites | /api/Favourites |
GET, GET by ID, POST, PUT, DELETE |
| Followings | /api/Followings |
GET, GET by ID, POST, PUT, DELETE |
| User profiles | /api/UserProfiles |
GET, GET by ID, POST, PUT, DELETE |
| Users | /api/Users |
Admin policy; GET, POST, PUT, DELETE |
| API keys | /api/Apikeys |
Admin policy; GET, POST, PUT, DELETE |
| Health | /health |
Anonymous GET |
The admin policy accepts either the admin role or a scope claim containing palette.admin. User responses never include password hashes. API-key list and detail responses never include the stored key; the generated value is returned only by the create operation.
PaletteCoreAPI/
├── .github/workflows/ci.yml Build and test automation
├── PaletteCoreAPI/
│ ├── Contracts/ Validated public API contracts
│ ├── Controllers/ Authenticated HTTP endpoints
│ ├── Migrations/ EF Core database migration
│ ├── Models/ Entities and PaletteContext
│ └── Program.cs Services and HTTP pipeline
├── PaletteCoreAPI.Tests/ Integration and contract tests
├── PaletteCoreAPI.sln
└── global.json
- .NET SDK 10.0.302 or a compatible .NET 10 SDK
- SQL Server
- an OpenID Connect or OAuth 2.0 authority that issues JWT access tokens
The repository contains no database password, identity-provider secret, or production endpoint. Use .NET user secrets from the API project:
dotnet user-secrets --project PaletteCoreAPI/PaletteCoreAPI.csproj set \
"ConnectionStrings:Database" \
"Server=localhost;Database=Palette;Integrated Security=True;TrustServerCertificate=True"
dotnet user-secrets --project PaletteCoreAPI/PaletteCoreAPI.csproj set \
"Authentication:Authority" \
"https://identity.example.com"
dotnet user-secrets --project PaletteCoreAPI/PaletteCoreAPI.csproj set \
"Authentication:Audience" \
"palette-api"Use a connection string and authority appropriate for your environment. Production configuration should come from the deployment platform's secret store or environment variables.
dotnet tool restore
export ConnectionStrings__Database='Server=localhost;Database=Palette;Integrated Security=True;TrustServerCertificate=True'
dotnet tool run dotnet-ef database update --project PaletteCoreAPI/PaletteCoreAPI.csprojdotnet restore PaletteCoreAPI.sln
dotnet build PaletteCoreAPI.sln --configuration Release --no-restore
dotnet test PaletteCoreAPI.sln --configuration Release --no-build
dotnet run --project PaletteCoreAPI/PaletteCoreAPI.csprojThe development launch profile opens Swagger UI at https://localhost:7042/swagger. The public health probe is available at https://localhost:7042/health.
The modernized solution builds with zero warnings and zero errors. The automated suite verifies that:
- the health endpoint remains public;
- representative domain routes reject anonymous access;
- public contracts do not expose password or stored API-key fields.
This repository no longer contains a fallback database connection string. Authentication configuration is external, entity types are not accepted as public request bodies, passwords are hashed before persistence, and administrative resources require an explicit policy.
The API delegates token issuance, account recovery, key rotation, rate limiting, and operational monitoring to surrounding infrastructure. Those production concerns must be configured by the deploying environment.
Serkan Seker