Skip to content

Commit 1e4cf20

Browse files
committed
feat: add Product Controller and resources
1 parent 7302f37 commit 1e4cf20

9 files changed

+196
-16
lines changed
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Http\Resources\ProductCollection;
6+
use App\Http\Resources\ProductResource;
7+
use App\Models\Product;
8+
use App\Services\ProductService;
9+
use Illuminate\Http\JsonResponse;
10+
11+
class ProductController extends Controller
12+
{
13+
14+
protected ProductService $productService;
15+
16+
public function __construct(ProductService $productService)
17+
{
18+
$this->productService = $productService;
19+
}
20+
21+
22+
/**
23+
* Scrape Product Page on Amazon and Store info
24+
*
25+
* @param String $asin
26+
*
27+
* @return JsonResponse
28+
*/
29+
public function scrapeProduct(string $asin): JsonResponse
30+
{
31+
try {
32+
$this->productService->handleScrapeProduct($asin);
33+
34+
return response()->json(
35+
$this->productService->getProduct($asin),
36+
200
37+
);
38+
} catch (\Exception $e) {
39+
logger($e->getMessage());
40+
41+
return response()->json([
42+
'message' => 'Impossible Scrape Product ' . $asin
43+
], 404);
44+
}
45+
}
46+
47+
48+
/**
49+
* Fetch All Products
50+
*
51+
* @return JsonResponse
52+
*/
53+
public function index()
54+
{
55+
return new ProductCollection(Product::all());
56+
}
57+
58+
/**
59+
* Fetch single Product
60+
*
61+
* @param String $asin
62+
* @return JsonResource
63+
*/
64+
public function show(string $asin)
65+
{
66+
return $this->productService->getProduct($asin);
67+
}
68+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\ResourceCollection;
6+
7+
class PriceCollection extends ResourceCollection
8+
{
9+
/**
10+
* Transform the resource collection into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return parent::toArray($request);
18+
}
19+
}

app/Http/Resources/PriceResource.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
7+
class PriceResource extends JsonResource
8+
{
9+
/**
10+
* Transform the resource into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return [
18+
'price' => $this->price,
19+
'at' => $this->updated_at
20+
];
21+
}
22+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\ResourceCollection;
6+
7+
class ProductCollection extends ResourceCollection
8+
{
9+
/**
10+
* Transform the resource collection into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return parent::toArray($request);
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
7+
class ProductNotFoundResource extends JsonResource
8+
{
9+
/**
10+
* Transform the resource into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return [
18+
'message' => 'Product Not Found',
19+
'asin' => $this['asin']
20+
];
21+
}
22+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
7+
class ProductResource extends JsonResource
8+
{
9+
/**
10+
* Transform the resource into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return [
18+
'asin' => $this['product']->asin,
19+
'name' => $this['product']->name,
20+
'price' => $this['product']->last_price,
21+
'prices' => $this['product']->prices ? new PriceCollection($this['product']->prices) : [],
22+
'category' => new CategoryResource($this['product']->category),
23+
'categories' => $this['categories']
24+
];
25+
}
26+
}

app/Repositories/ProductRepository.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ public function updatePrice(Product $product, float $productPrice): ?Price
4747
'product_asin' => $product->asin,
4848
'price' => $productPrice
4949
])
50-
: $product->last_price;
50+
: Price::where('product_asin', $product->asin)
51+
->orderBy('created_at', 'desc')
52+
->first();
5153
}
5254

5355
/**

app/Services/ProductService.php

+13-12
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
namespace App\Services;
44

55
use App\Http\Resources\CategoryResource;
6+
use App\Http\Resources\ProductNotFoundResource;
7+
use App\Http\Resources\ProductResource;
8+
use App\Models\Product;
69
use App\Repositories\CategoryRepositoryInterface;
710
use App\Repositories\ProductRepositoryInterface;
811
use Goutte\Client;
912
use Illuminate\Http\JsonResponse;
13+
use Illuminate\Http\Resources\Json\JsonResource;
1014
use NumberFormatter;
1115

1216
class ProductService
@@ -89,28 +93,25 @@ public function handleScrapeProduct(string $asin): bool
8993
*
9094
* @param String $asin
9195
*
92-
* @return JsonResponse
96+
* @return JsonResource
9397
*/
94-
public function getProduct(string $asin): JsonResponse
98+
public function getProduct(string $asin): JsonResource
9599
{
96100
try {
97101
$product = $this->productRepository->getProduct($asin);
98102

99103
$categories = $this->categoryRepository->getAllParent($product->category);
100104

101-
return response()->json([
102-
'asin' => $product->asin,
103-
'name' => $product->name,
104-
'price' => $product->last_price,
105-
'category' => new CategoryResource($product->category),
106-
'categories' => $categories
107-
], 200);
105+
return new ProductResource([
106+
'product' => $product,
107+
'categories' => array_reverse($categories)
108+
]);
108109
} catch (\Exception $e) {
109110
logger($e->getMessage());
110111

111-
return response()->json([
112-
'message' => 'Product not found'
113-
], 404);
112+
return new ProductNotFoundResource([
113+
'asin' => $asin
114+
]);
114115
}
115116
}
116117
}

routes/api.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use App\Http\Controllers\ProductController;
34
use Illuminate\Http\Request;
45
use Illuminate\Support\Facades\Route;
56

@@ -14,6 +15,6 @@
1415
|
1516
*/
1617

17-
Route::middleware('auth:api')->get('/user', function (Request $request) {
18-
return $request->user();
19-
});
18+
Route::get('/product/{asin}', [ProductController::class, 'show']);
19+
Route::get('/products', [ProductController::class, 'index']);
20+
Route::get('/scrape/{asin}', [ProductController::class, 'scrapeProduct']);

0 commit comments

Comments
 (0)