A RESTful API backend built with Laravel 12 for managing products and categories. The system uses JWT authentication, supports image uploads, and sends queue-based email notifications on product create/update.
- Laravel 12
- JWT Authentication (
tymon/jwt-auth) - MySQL
- Laravel Queue (Database driver)
- Mail (Product create/update notification)
- File Storage (Product images)
- User Registration & Login (JWT)
- Category CRUD
- Product CRUD
- Product Image Upload
- Email notification on product create/update
- Queue-based background jobs
- Pagination & Eloquent relationships
- Secure API routes with JWT
git clone https://github.com/daief48/backend.git
cd inventory-system/backendcomposer installcp .env.example .env
php artisan key:generate
php artisan jwt:secretUpdate .env with your database and mail credentials.
php artisan migrate
php artisan queue:table
php artisan migratephp artisan storage:linkphp artisan queue:workphp artisan serveBackend URL:
http://127.0.0.1:8000
Base URL:
http://127.0.0.1:8000/api
Authentication: JWT (Bearer Token)
All category & product routes require authentication.
POST /register
Request Body (JSON)
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}Success Response (201)
{
"message": "User registered successfully",
"token": "jwt_token_here",
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
}POST /login
Request Body (JSON)
{
"email": "john@example.com",
"password": "password123"
}Success Response (200)
{
"token": "jwt_token_here",
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
}POST /logout
Headers
Authorization: Bearer jwt_token_here
Response (200)
{
"message": "Logged out successfully"
}GET /categories
Response (200)
[
{
"id": 1,
"name": "Electronics",
"created_at": "2025-01-01",
"updated_at": "2025-01-01"
}
]POST /categories
Request Body (JSON)
{
"name": "Fashion"
}Response (201)
{
"id": 2,
"name": "Fashion",
"created_at": "2025-01-01",
"updated_at": "2025-01-01"
}PUT /categories/{id}
Request Body (JSON)
{
"name": "Home Appliances"
}Response (200)
{
"id": 1,
"name": "Home Appliances"
}DELETE /categories/{id}
Response (204)
No Content
GET /products
Response (200)
{
"data": [
{
"id": 1,
"name": "Wireless Mouse",
"description": "Ergonomic mouse",
"price": 850,
"image": "products/mouse.jpg",
"category": {
"id": 1,
"name": "Electronics"
}
}
],
"current_page": 1,
"per_page": 10
}POST /products
Request (multipart/form-data)
name: Wireless Mouse
description: Ergonomic mouse
price: 850
category_id: 1
image: mouse.jpg
Response (201)
{
"id": 1,
"name": "Wireless Mouse",
"price": 850,
"category_id": 1
}📧 Triggers email job (ProductMailJob)
PUT /products/{id}
Request (multipart/form-data)
name: Updated Mouse
price: 900
category_id: 1
Response (200)
{
"id": 1,
"name": "Updated Mouse",
"price": 900
}📧 Triggers email job (ProductMailJob)
DELETE /products/{id}
Response (204)
No Content
{
"message": "The given data was invalid",
"errors": {
"name": ["The name field is required."]
}
}Authorization: Bearer your_jwt_token_here
- Images are stored in
storage/app/public/products - Products are paginated (10 per page)
- JWT token required for protected routes
- Email notification jobs run via Laravel Queue
🎯 This README is production-ready and suitable for GitHub, portfolio, or technical assessments.