Backend: REST API
Relevant source files
The following files were used as context for generating this wiki page:
The PriceBuddy REST API provides a programmatic interface for interacting with core application resources, primarily Products and Tags. Built on the Laravel framework, it leverages the rupadana/filament-api-service package to expose functionality defined within the Filament admin panel resources. This creates a consistent and auto-generated API structure.
All API endpoints are secured and require token-based authentication via Laravel Sanctum. The API is designed with multi-tenancy in mind, ensuring that users can only access and manage their own data. It supports standard RESTful conventions, including CRUD operations, pagination, filtering, sorting, and relationship inclusion.
Architecture
The API's architecture is tightly integrated with the Filament resource management system. The rupadana/filament-api-service package acts as a bridge, translating HTTP requests into actions on Filament resources, which in turn interact with the underlying Eloquent models.
This diagram illustrates the high-level flow of an API request.
Core Components
| Component | Description | Source |
|---|---|---|
rupadana/filament-api-service | A Laravel package that automatically generates REST API endpoints from Filament resources. | composer.json:16 |
ApiService Classes | Service classes like TagApiService define which handlers (Create, Update, etc.) are available for a given resource. | app/Filament/Resources/TagResource/Api/TagApiService.php:6-16 |
| Laravel Sanctum | Provides token-based authentication for all API endpoints. | tests/Feature/Api/ProductApiTest.php:19-21 |
| Filament Resources | Define the schema, table structure, and actions for models like Product and Tag. The API service reuses this logic. | app/Filament/Resources/TagResource.php |
Authentication
The API is protected and requires a bearer token for all requests. Authentication is handled by Laravel Sanctum. A user can create a token which must then be included in the Authorization header of subsequent API calls.
// Example of token creation for tests
$this->user = User::factory()->create();
$token = $this->user->createToken('test-token')->plainTextToken;
$this->withHeaders(['Authorization' => 'Bearer '.$token]);
Sources: tests/Feature/Api/ProductApiTest.php:18-21, tests/Feature/Api/TagApiTest.php:16-19
Requests without a valid token will receive a 401 Unauthorized response.
Sources: tests/Feature/Api/ProductApiTest.php:400-406, tests/Feature/Api/TagApiTest.php:336-342
Authentication Flow
The following diagram shows the sequence for an authenticated API call.
Security & Authorization
A critical aspect of the API is its multi-tenant security model. Users are strictly sandboxed and can only interact with their own resources. Any attempt to access, update, or delete another user's data will result in a 404 Not Found response, effectively hiding the existence of the resource from unauthorized users.
This is enforced by scoping database queries to the authenticated user's ID.
API Endpoints
The API provides RESTful endpoints for managing Products and Tags.
Product API (/api/products)
This set of endpoints manages product tracking.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/products | Lists all products belonging to the authenticated user. Supports pagination, sorting, and filtering. |
POST | /api/products | Creates a new product. Requires a title and url. Triggers an initial web scrape for product details. |
GET | /api/products/{id} | Retrieves a single product by its ID. |
PUT | /api/products/{id} | Updates the details of a specific product. |
DELETE | /api/products/{id} | Deletes a product and its associated data. |
Sources: [tests/Feature/Api/ProductApiTest.php]
Product Data Model
The Product resource has the following main attributes exposed via the API.
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier for the product. |
title | string | The name of the product. |
image | string | URL of the product's primary image. |
status | string | The status of the product (e.g., published, archived). |
notify_price | float | The target price for notifications. |
notify_percent | float | The target percentage drop for notifications. |
favourite | boolean | Whether the product is marked as a favourite. |
created_at | datetime | Timestamp of when the product was created. |
updated_at | datetime | Timestamp of the last update. |
Sources: tests/Feature/Api/ProductApiTest.php:43-58, [app/Models/Product.php]
Features & Usage
Filtering
Products can be filtered by their attributes using the filter query parameter.
- Filter by status:
GET /api/products?filter[status]=published - Filter by favourite:
GET /api/products?filter[favourite]=true
Sources: tests/Feature/Api/ProductApiTest.php:322-345
Sorting
Results can be sorted by any attribute. Prepend a - for descending order.
- Sort by title ascending:
GET /api/products?sort=title - Sort by creation date descending:
GET /api/products?sort=-created_at
Sources: tests/Feature/Api/ProductApiTest.php:347-366
Including Relationships
Related data can be eager-loaded using the include parameter.
- Include tags and user:
GET /api/products/{id}?include=tags,user
Sources: tests/Feature/Api/ProductApiTest.php:368-382
Pagination
The API uses paginated responses. The number of items per page can be controlled with the per_page parameter. The response includes data, links, and meta objects.
- Get 10 items per page:
GET /api/products?per_page=10
Sources: tests/Feature/Api/ProductApiTest.php:384-400
Tag API (/api/tags)
This set of endpoints manages product tags.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/tags | Lists all tags belonging to the authenticated user. |
POST | /api/tags | Creates a new tag. name must be unique per user. |
GET | /api/tags/{id} | Retrieves a single tag by its ID. |
PUT | /api/tags/{id} | Updates the name of a specific tag. |
DELETE | /api/tags/{id} | Deletes a tag and its associations with products. |
Sources: [tests/Feature/Api/TagApiTest.php]
Tag Data Model
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier for the tag. |
name | string | The name of the tag. |
user_id | integer | The ID of the user who owns the tag. |
created_at | datetime | Timestamp of when the tag was created. |
updated_at | datetime | Timestamp of the last update. |
Sources: tests/Feature/Api/TagApiTest.php:35-46
Features & Usage
Searching and Filtering
- Search by name:
GET /api/tags?search=Elect - Filter by exact name:
GET /api/tags?filter[name]=Electronics
Sources: tests/Feature/Api/TagApiTest.php:280-309
Sorting
- Sort by name:
GET /api/tags?sort=name - Sort by creation date descending:
GET /api/tags?sort=-created_at
Sources: tests/Feature/Api/TagApiTest.php:229-261
Including Relationships
- Include associated products:
GET /api/tags/{id}?include=products
Sources: tests/Feature/Api/TagApiTest.php:263-278
Summary
The PriceBuddy REST API provides a robust, secure, and conventional way to manage application data. Its integration with Filament resources ensures that the API stays in sync with the admin panel's data definitions. The strict, user-scoped authorization model guarantees data privacy in a multi-user environment. The API's support for modern features like filtering, sorting, and relationship embedding makes it a flexible tool for building client applications or external integrations.