A multi-project e-commerce backend built with C#, .NET 10, ASP.NET Core Web API, Entity Framework Core, SQL Server, Redis, JWT, and Stripe.
The project explores backend application architecture, identity, product catalog queries, basket and order workflows, caching, and payment-intent integration.
- Product catalog endpoints with filtering, pagination, and specification-based queries.
- User registration and authentication using ASP.NET Core Identity and JWT.
- Customer basket operations backed by the basket repository.
- Order creation and retrieval, including order items and delivery methods.
- Stripe payment-intent integration.
- Redis-backed basket and caching infrastructure, with HybridCache configuration.
- Token-bucket rate limiting for search-related requests.
- EF Core migrations and startup seeding for sample catalog and identity data.
- OpenAPI documentation with Scalar for exploring the API.
- Language / Runtime: C#, .NET 10
- API: ASP.NET Core Web API
- Persistence: Entity Framework Core, SQL Server
- Authentication: ASP.NET Core Identity, JWT
- Caching: Redis, HybridCache, in-memory cache
- Payments: Stripe
- API Docs: OpenAPI, Scalar
Backend/
Talabat.Api/
Talabat.Application/
Talabat.Domain/
Talabat.Infrastructure/
Talabat.sln
Frontend/
Talabat.Web/
docs/
| Project | Responsibility |
|---|---|
Talabat.Domain |
Business entities, repository contracts, and query specifications |
Talabat.Application |
Use cases, application contracts, API-facing DTOs, and mapping |
Talabat.Infrastructure |
EF Core persistence, repository implementations, migrations, Redis, Stripe, and identity |
Talabat.Api |
HTTP endpoints, authentication configuration, filters, static files, and API documentation |
Dependencies point inward: the API composes Application and Infrastructure, Infrastructure implements the contracts, and Domain remains independent of persistence.
- .NET 10 SDK
- SQL Server
- Redis
- Stripe test credentials for payment-intent flows
From the repository root:
dotnet restore Backend/Talabat.sln
dotnet user-secrets init --project Backend/Talabat.Api/Talabat.Api.csprojConfigure secrets locally instead of committing them to appsettings.json:
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "YOUR_SQL_SERVER_CONNECTION_STRING" --project Backend/Talabat.Api/Talabat.Api.csproj
dotnet user-secrets set "ConnectionStrings:Identity" "YOUR_IDENTITY_DATABASE_CONNECTION_STRING" --project Backend/Talabat.Api/Talabat.Api.csproj
dotnet user-secrets set "JwtSettings:SecretKey" "YOUR_LONG_RANDOM_JWT_SECRET" --project Backend/Talabat.Api/Talabat.Api.csproj
dotnet user-secrets set "StripeSettings:Secretkey" "YOUR_STRIPE_TEST_SECRET_KEY" --project Backend/Talabat.Api/Talabat.Api.csprojMake sure Redis is reachable at the configured ConnectionStrings:Redis address. The repository defaults this to localhost.
Start the API:
dotnet run --project Backend/Talabat.Api/Talabat.Api.csprojCreate EF Core migrations in the Infrastructure project and use the API as the startup project:
dotnet ef migrations add <MigrationName> --project Backend/Talabat.Infrastructure/Talabat.Infrastructure.csproj --startup-project Backend/Talabat.Api/Talabat.Api.csproj --context StoreContext
dotnet ef migrations add <MigrationName> --project Backend/Talabat.Infrastructure/Talabat.Infrastructure.csproj --startup-project Backend/Talabat.Api/Talabat.Api.csproj --context AppIdentityDbContext --output-dir Identity/MigrationsOn startup, the application attempts to apply EF Core migrations and seed sample data. The database connections must be configured and SQL Server must be available before relying on the seeded data.
In Development, OpenAPI is mapped by the application and Scalar is available for interactive API exploration. Use the URL printed by dotnet run as the base address.
The storefront is a separate Angular 21 project in Frontend/Talabat.Web. It uses the API for the catalog, account, basket, delivery options, Stripe payment intents, orders, and cache-key diagnostics. The frontend does not contain backend secrets.
The local Compose file runs the API and storefront in separate containers. It reads the existing API User Secrets file read-only; no credentials are copied into the repository or frontend image. SQL Server and Redis remain in their existing containers.
docker compose up --build -dOpen http://127.0.0.1:4200. The Angular container proxies API and product-image requests to the API container. Both app containers use the Linux host network so they can reach the existing SQL Server and Redis containers through their loopback ports. The API User Secrets file must exist at the normal .NET Linux User Secrets location for this project.
To run either project outside Docker, start the API on http://127.0.0.1:5080:
dotnet run --project Backend/Talabat.Api/Talabat.Api.csproj --urls http://127.0.0.1:5080Then use a terminal in Frontend/Talabat.Web:
npm ci
npm startThe Angular development proxy in Frontend/Talabat.Web/proxy.conf.json forwards to http://127.0.0.1:5080. Stop the app containers with:
docker compose downSee docs/architecture.md for the backend/frontend hierarchy, Angular file roles, and request workflows. VS Code recommends Angular Language Service and Redis for VS Code; install the recommendations when prompted. In Redis for VS Code, connect to the same Redis host and port configured under ConnectionStrings:Redis to browse live cache keys and values. Keep Redis credentials in the extension's connection profile, not in the repository.
- Never commit real SQL Server credentials, JWT signing keys, or Stripe secret keys.
- Use .NET User Secrets for local development and environment variables or a managed secret store for deployment.
- Use Stripe test credentials during development.
- The Stripe publishable key is not a substitute for the secret key; keep the secret key private.
- Organizing a backend solution into domain, application, infrastructure, and API projects.
- Using repositories, Unit of Work, and specifications to structure data access.
- Implementing identity, token-based authentication, caching, and rate limiting.
- Connecting order workflows to payment-intent handling.
- Documenting and testing an API through OpenAPI tooling. .