Create e-commerce Web API#96
Conversation
Fix UnitOfWork performance issue or creating a new object each time needed in a request.
Update "delete" logic in GenericRepository
…lAsync and GetByIdAsync
# This is the 1st commit message: Add pagination support to GetAllAsync and include properties to GetAllAsync and GetByIdAsync # The commit message the-csharp-academy#2 will be skipped: # fixup! Add pagination support to GetAllAsync and include properties to GetAllAsync and GetByIdAsync
Fix category including property to product. Fix a repository method to be async
…n and include properties.
…nd CreateSale business logic.
…d set accessors for better type safety.
…o assign the parameter from query string
Added detailed documentation for the E-commerce API, including features, architecture, technologies, installation instructions, API endpoints, usage examples, and future enhancements.
Removed contributing guidelines and license section.
…oller to use FluentValidation for validation.
… names and error messages in ProductController
…troller to use FluentValidation for validation.
Created input validation and exception handling from the future enhancements section and added to the features section.
Updated exception handling and input validation sections for clarity and consistency.
Updated README to reflect API versioning and added FluentValidation details.
Updated the status of the authentication & authorization task to indicate it is currently in progress.
chrisjamiecarter
left a comment
There was a problem hiding this comment.
Hey @basemkasem 👋,
Excellent work on your E-commerce API project submission 🎉!
I have performed a peer review. Review/ignore any comments as you wish.
Your code demonstrates a solid understanding of Clean Architecture with excellent separation of concerns across Core, Data, Services, and Web layers. The implementation includes sophisticated features like the Result pattern for error handling, FluentValidation for input validation, API versioning, soft delete pattern, and pagination support. The build succeeds and the code structure is well-organized.
🟠 Project Submission
💡 Please place all your code inside a single top-level folder named: [ProjectName].[UserName].
👨🏫 Example: EcommerceApi.basemkasem
📁 CodeReviews.Console.EcommerceApi ⬅️ Forked repo
┣ 📄 .codacy.yml
┣ 📄 .gitignore
┣ 📁 EcommerceApi.basemkasem ❗ Should be this
┃ ┗ 📄 Project.sln ✅
┃ ┗ 📄 README.md ❗Should be here not root
┃ ┗ 📁 EcommerceApi.Core ✅
┃ ┗ 📁 EcommerceApi.Data ✅
┃ ┗ 📁 EcommerceApi.Service ✅
┃ ┗ 📁 EcommerceApi.Web ✅
💭 This helps me clearly identify your work and confirms you can work within community repository guidelines.
I will go ahead and mark as approved, keep up the excellent work on the next projects! 😊
Best regards,
@chrisjamiecarter 👍
| @@ -0,0 +1,8 @@ | |||
| namespace Ecommerce.Core.DTOs.Category; | |||
|
|
|||
| public class CategoryDto | |||
There was a problem hiding this comment.
🟡 Class vs Record
💭 Nothing wrong here, just think of the benefits of using a record here instead of a class.
|
|
||
| namespace Ecommerce.Core.Interfaces.Repositories; | ||
|
|
||
| public interface IGenericRepository<T> where T : class |
There was a problem hiding this comment.
🔵 Generic Repositories
❓ Interesting, did you implement generic repositories for learning, or do you actually prefer using them?
|
|
||
| namespace Ecommerce.Core.Interfaces.Repositories; | ||
|
|
||
| public interface IUnitOfWork |
There was a problem hiding this comment.
🔵 Unit of Work
❓ I know you have implemented CA and app should not know about infra, but should unit of work be defined here as a contract? Also as you are using EFCore in Infra, that already implements the UoW pattern, so is kind of pointless.
| RuleFor(x => x.Name) | ||
| .NotEmpty() | ||
| .WithMessage("Category name is required.") | ||
| .MaximumLength(50) |
There was a problem hiding this comment.
🟡 Magic Numbers
💡 Move magic numbers like this into the entity, so the single source of truth lives there instead of every single validator.
| public DbSet<SaleItem> SaleItems { get; set; } | ||
|
|
||
|
|
||
| protected override void OnModelCreating(ModelBuilder modelBuilder) |
There was a problem hiding this comment.
🟡 Configuration Classes
💡 Consider creating configuration classes for your entities and holding this information there instead of here in AppDbContext, then applying by calling modelBuilder.ApplyConfigurationsFromAssembly; instead.
|
|
||
| app.MapControllers(); | ||
|
|
||
| app.Run(); No newline at end of file |
There was a problem hiding this comment.
🟠 Missing Database Initialization
💡 The application doesn't initialize the database on startup. I would recommend for C# academy project submissions you add EnsureCreated or Migrate to ensure the database is created/migrated. I know your README covers this, but one of your jobs is to make it as frictionless for the reviewer as possible.
| } | ||
| }, | ||
| "AllowedHosts": "*" | ||
| } |
There was a problem hiding this comment.
🟠 Missing Connection String
💡 Again, I know this is covered in the README, but the appsettings.json is missing the required "ConnectionStrings" section. You should at least have a dummy/placeholder value in here. I assume you are using user secrets for the actual connection string on your machine which is best practice.
| Price = product.Price, | ||
| CategoryId = product.CategoryId | ||
| }; | ||
| if(newProduct.Quantity <= 0) |
There was a problem hiding this comment.
🟠 Domain Concern
💡 This logic is probably a Domain rule and should be on the entity. Also would be true for Quantity == 0 which is not negative like the fail message suggests.
| int rowsAffected = await _unitOfWork.CompleteAsync(); | ||
| if (rowsAffected == 0) | ||
| { | ||
| return Result<ProductDto>.Fail("Failed to create category"); |
There was a problem hiding this comment.
🟡 Error Message References Wrong Entity
💡 When creation fails, the error message says "Failed to create category" but it's actually creating a Product. This should say "Failed to create product".
No description provided.