If you want to know what to ask I’d recommend telling it you want to ensure your code is clean, single responsibility, extensible, and testable.
I think when you work with these big frameworks the more important thing as a junior imo would be to make sure you understand the underlying tech (db, network basics, etc) and the latest framework conventions. Just keep it simple.
The truth is that engineering is very opinionated, and you've picked an opinionated framework.
I don't know php/laravel, but I've worked on Rails/Elixir/etc frameworks. Having interviewed juniors in technical rounds, I'm telling you that the more important thing for you (I take it you're a fresh junior?) is to understand the framework's conventions and be able to navigate that well enough. Can you code in php? Once you're on the job, you'll find that those conventions tend to go out the door when there's actual money on the line, so the best you can do is be aware and on top of it.
Also, to be honest, without knowing php/laravel, the best I can do while I'm on my phone (take it or leave it, or use Claude/AI - I am self taught and nobody code reviewed me when I started)
- Return custom errors instead of strings. Like NotFoundError, ForbiddenError, etc. This way you have some consistency, and you can include like code, message or whatever fields for better API user experience
- If there are no Products, just return an empty list instead of a string like "No products found"
- When you delete you can just return the ID or even nothing (just a 200 OK)
- Use proper http codes. I'm not sure if laravel handles that automatically, or you need to do like 201 for create, for example.
Anyway good luck man, if you're new you're in for a world of wonder :-)
Also try any Php/Laravel Slack/Discord communities too. They will be more helpful!
<?php
namespace App\Services;
use App\Models\Product; use App\Models\Category; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\Collection;
class ProductService {
public function store(array $data, string $category_id): Product {
$product_to_save = new Product([
'name' => $data['name'],
'slug' => $data['slug'],
'description' => $data['description'],
'price' => $data['price'],
'sku' => $data['sku'],
'stock_quantity' => $data['stock_quantity'],
]);
$category = Category::findOrFail($category_id);
$product = $category->products()->save($product_to_save);
return $product;
}
public function getProductsByCategory(string $category_name): Collection {
$category = Category::where('name', $category_name)->firstOrFail();
return $category->products()->with('category')->get();
}
public function detail(string $id): Product {
$product = Product::findOrFail($id);
return $product;
}
public function index(): Collection {
$product = Product::all();
if ($product->isEmpty()) {
throw (new ModelNotFoundException)->setModel(Product::class);
}
return $product;
}
public function delete(string $id){
$product = Product::findOrFail($id);
$product->delete();
return $product;
}
public function checkStock(string $id): Boolean {
$in_stock = null;
$product = Product::findOfFail($id);
$product_stock = $product->stock_quantity;
if($product_stock > 0){
$in_stock = true;
}
if($product_stock == 0){
$in_stock = false;
}
return $in_stock;
}
public function updateProductStock(string $id, int $amount): Boolean {
$product = Product::findOrFail($id);
if($amount < 0) {
return false;
} else {
$product->stock_quantity = $amount;
$product->save();
return true;
}
}
public function applyDiscount(string $id, float $percentage): Boolean {
$product = Product::findOrFail($id);
if ($percentage <= 0 || $percentage > 100) {
return false;
}
$discount_amount = $product->price * ($percentage / 100);
$new_price = $product->price - $discount_amount;
$product->price = max(0, $new_price);
$product->save();
return true;
}
public function makeProductFeatured(string $id): Boolean {
$product = Product::findOrFail($id);
$product->is_featured = true;
$product->save();
return true;
}
public function getAllFeaturedProducts(): Collection {
$featured_products = Product::where('is_featured', true)->with('category')->get();
return $featured_products;
}
}<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request; use App\Services\ProductService; use Illuminate\Http\JsonResponse;
class ProductController extends Controller { //
public function __construct(ProductService $productService) {
$this->productService = $productService;
}
public function store(Request $request): JsonResponse {
$category_id = $request->category_id;
$validated_data = $request->validate([
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:255',
'price' => 'required|numeric',
'sku' => 'required|string|max:255',
'stock_quantity' => 'required|numeric',
]);
//$path = $request->file('image')->store('images', 'public');
$product = $this->productService->store($validated_data, $category_id);
return response()->json([
'product' => $product,
]);
}
public function getProductsByCategory(string $category_name): JsonResponse {
$product = $this->productService->getProductsByCategory($category_name);
return response()->json([
'products' => $product,
]);
}
public function index(): JsonResponse {
$product = $this->productService->index();
return response()->json([
'products' => $product,
]);
}
public function detail(string $id): JsonResponse {
$product = $this->productService->detail($id);
return response()->json([
'product' => $product,
]);
}
public function delete(string $id): JsonResponse {
$product = $this->productService->delete($id);
return response()->json([
'product' => $product,
]);
}
}<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany;
class Product extends Model { // use SoftDeletes;
protected $fillable = [
'category_id',
'name',
'slug',
'description',
'short_description',
'price',
'compare_at_price',
'sku',
'stock_quantity',
'is_featured',
'is_active',
'weight',
'dimensions',
];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function product_images(): HasMany
{
return $this->hasMany(ProductImage::class);
}
public function reviews(): HasMany
{
return $this->hasMany(Review::class);
}
public function productskus(): HasMany
{
return $this->hasMany(ProductSku::class);
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class);
}
}This compared to the code from code review stack overflow is a major changer I guess... Like I said everything you said and more lined up pretty clearly, of course there is always room for making the code better, but it's a start I guess...