A simple bookstore REST API built with ASP.NET Core and C# using Identity for user management, JWT authentication, and PostgreSQL (Entity Framework Core). This repository contains the API, models, and migration/seed logic required to run locally and deploy.
- Stack: ASP.NET Core (.NET 9), C#, Entity Framework Core, PostgreSQL, ASP.NET Identity, JWT
- Authentication: JWT stored in an HttpOnly cookie named jwt (also supports Authorization header)
- Roles seeded at startup: Admin, Member
- Implemented features: Book CRUD, Author CRUD, Shopping Cart, Search & Filter, Order Processing
- .NET SDK 9.0 (install from https://dotnet.microsoft.com)
- PostgreSQL
- Git
Controllers/ — API controllers (AuthController, BooksController, AuthorsController, CartController, OrdersController, etc.) Models/ — ApplicationUser, DTOs (RegisterModel, LoginModel), domain models (Book, Author, Order, CartItem), BookStoreContext (DbContext) Program.cs — app configuration (Identity, JWT, CORS, Swagger), Seed data (roles, sample data) README.md — this file
- Clone the repository
git clone https://github.com/ayaz9988/test-repo.git
cd test-repo- Configure secrets (do NOT commit secrets)
- Initialize user-secrets in the project folder containing the .csproj:
dotnet user-secrets init
dotnet user-secrets set "Jwt:Key" "REPLACE_WITH_STRONG_SECRET"
dotnet user-secrets set "Jwt:Issuer" "your-issuer"
dotnet user-secrets set "Jwt:Audience" "your-audience"
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Host=localhost;Database=bookstore;Username=postgres;Password=..."- Or set environment variables:
Linux/macOS:
export Jwt__Key="REPLACE_WITH_STRONG_SECRET"
export Jwt__Issuer="your-issuer"
export Jwt__Audience="your-audience"
export ConnectionStrings__DefaultConnection="Host=localhost;Database=bookstore;Username=postgres;Password=..."Windows PowerShell:
setx Jwt__Key "REPLACE_WITH_STRONG_SECRET"
setx Jwt__Issuer "your-issuer"
setx Jwt__Audience "your-audience"
setx ConnectionStrings__DefaultConnection "Host=localhost;Database=bookstore;Username=postgres;Password=..."3.Create the database and apply migrations
- If migrations exist:
dotnet ef database update- If there are no migrations, add and apply:
dotnet ef migrations add InitialCreate
dotnet ef database update- Run the app
dotnet run- Swagger UI (development): https://localhost:5001 (or the port shown). Use it to test register/login and CRUD endpoints.
Authentication:
- POST /api/auth/register — Register user Body: { email, password, name, phone, address, role? }
- POST /api/auth/login — Login (sets HttpOnly cookie jwt and/or returns token) Body: { email, password }
- POST /api/auth/logout — Logout (clears jwt cookie)
Authors:
- GET /api/authors — List authors
- GET /api/authors/{id} — Get author by id
- POST /api/authors — Create author (Admin) Body: { name, biography, birthDate }
- PUT /api/authors/{id} — Update author (Admin) Body: { authorId, name, biography, birthDate } = DELETE /api/authors/{id} — Delete author (Admin)
Books:
- GET /api/books — List books
- GET /api/books/{id} — Get book by id
- POST /api/books — Create book (Admin) Body: { Title, ISBN, Price, StockQuantity, AuthorId, CategoryIds[] }
- PUT /api/books/{id} — Update book (Admin) Body: { bookId, title, author, isbn, price, stockQuantity }
- DELETE /api/books/{id} — Delete book (Admin)
- GET /api/books/search — Search & filter books (query params) search — term for title/author/description genre — genre name minPrice, maxPrice — numeric range categoryIds — comma-separated ids (e.g., categoryIds=1,5)
Categories:
- GET /api/categories — List categories
- GET /api/categories/{id} — Get category by id
- POST /api/categories — Create category (Admin) Body: { name, description }
- PUT /api/categories/{id} — Update category (Admin) Body: { categoryId, name, description }
- DELETE /api/categories/{id} — Delete category (Admin)
Shopping Cart:
- GET /api/shoppingcart — Get current user's cart (Auth required)
- POST /api/shoppingcart — Add item to cart (Auth required) Body: { bookId, quantity }
- PUT /api/shoppingcart/{itemId} — Update item quantity (Auth required) Body: { quantity }
- DELETE /api/shoppingcart/{itemId} — Remove item from cart (Auth required)
- DELETE /api/shoppingcart — Clear cart (Auth required)
Orders:
- POST /api/orders/checkout — Checkout current cart and create order (Auth required)
- GET /api/orders — List orders (Admin: all orders; Member: own orders)
- GET /api/orders/{id} — Get order by id (Admin or owner)
- GET /api/orders/{id}/status — Get order status (Auth required)
- PUT /api/orders/{id}/status — Update order status (Admin) Body: status value (e.g., "Complete")