A RESTful API for an Ecommerce platform built with Laravel.
- Full CRUD operations for users, products, categories, and orders
- Authentication using Laravel Sanctum
- Role-based authorization (admin/user)
- Robust validation and error handling
- Comprehensive API documentation
- Database migrations and seeders
- Feature tests
- Shopping cart functionality
- Product tags and search capabilities
- PHP 8.1 or higher
- Composer
- MySQL or PostgreSQL
- Clone the repository:
git clone https://github.com/yourusername/ecommerce-api.git
cd ecommerce-api- Install dependencies:
composer install- Create a copy of the
.env.examplefile:
cp .env.example .env- Generate an application key:
php artisan key:generate- Configure your database settings in the
.envfile:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ecommerce_api
DB_USERNAME=root
DB_PASSWORD=
- Run the migrations and seed the database:
php artisan migrate --seed- Start the development server:
php artisan serveThe API is available at http://localhost:8000/api.
- POST /api/register - Register a new user
- POST /api/login - Log in an existing user
- POST /api/logout - Log out a user (requires authentication)
- GET /api/user - Get authenticated user details (requires authentication)
- GET /api/products - List all products (public)
- GET /api/products/{product} - Get a specific product (public)
- POST /api/products - Create a product (admin only)
- PUT /api/products/{product} - Update a product (admin only)
- DELETE /api/products/{product} - Delete a product (admin only)
- GET /api/search/products?q={query} - Search products (public)
- GET /api/products/{id}/tags - Get all tags for a product (public)
- POST /api/products/{id}/tags - Attach tags to a product (admin only)
- PUT /api/products/{id}/tags - Update (sync) tags for a product (admin only)
- DELETE /api/products/{id}/tags/{tagId} - Remove a tag from a product (admin only)
- GET /api/categories - List all categories (public)
- GET /api/categories/{category} - Get a specific category (public)
- GET /api/categories/{category}/products - Get products in a category (public)
- POST /api/categories - Create a category (admin only)
- PUT /api/categories/{category} - Update a category (admin only)
- DELETE /api/categories/{category} - Delete a category (admin only)
- GET /api/tags - List all tags (public)
- GET /api/tags/{tag} - Get a specific tag (public)
- POST /api/tags - Create a tag (admin only)
- PUT /api/tags/{tag} - Update a tag (admin only)
- DELETE /api/tags/{tag} - Delete a tag (admin only)
- GET /api/tags/{tag}/products - Get products with a tag (public)
- GET /api/cart - Get the current user's cart (auth required)
- POST /api/cart/items - Add item to cart (auth required)
- PUT /api/cart/items/{id} - Update cart item (auth required)
- DELETE /api/cart/items/{id} - Remove item from cart (auth required)
- DELETE /api/cart - Clear the cart (auth required)
- GET /api/my-orders - List user's orders (requires authentication)
- GET /api/orders - List all orders (admin only)
- GET /api/orders/{order} - Get a specific order (owner or admin)
- POST /api/orders - Create an order (requires authentication)
- PUT /api/orders/{order}/status - Update order status (admin only)
After seeding the database, the following users will be available:
-
Admin:
- Email: admin@example.com
- Password: password
-
Regular User:
- Email: user@example.com
- Password: password
- Create a new environment in Postman called "Ecommerce API"
- Add the following variables:
base_url:http://localhost:8000api_url:{{base_url}}/apiauth_token: (will be set after login)
POST {{api_url}}/register
Headers:
Content-Type: application/json
Accept: application/json
Body (JSON):
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}Expected Response:
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"is_admin": false,
"created_at": "2025-06-13T10:00:00.000000Z"
},
"token": "1|abc123...xyz789"
}
}Test Script (Add to Postman Tests tab):
if (pm.response.code === 201) {
const response = pm.response.json();
if (response.data && response.data.token) {
pm.environment.set("auth_token", response.data.token);
}
}POST {{api_url}}/login
Headers:
Content-Type: application/json
Accept: application/json
Body (JSON):
{
"email": "admin@example.com",
"password": "password"
}Expected Response:
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": 1,
"name": "Admin User",
"email": "admin@example.com",
"is_admin": true
},
"token": "2|def456...uvw012"
}
}Test Script:
if (pm.response.code === 200) {
const response = pm.response.json();
if (response.data && response.data.token) {
pm.environment.set("auth_token", response.data.token);
}
}GET {{api_url}}/user
Headers:
Accept: application/json
Authorization: Bearer {{auth_token}}
POST {{api_url}}/categories
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"name": "Electronics",
"slug": "electronics",
"description": "Electronic devices and gadgets"
}POST {{api_url}}/products
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"name": "iPhone 15 Pro",
"slug": "iphone-15-pro",
"description": "Latest iPhone with advanced features",
"price": 999.99,
"stock_quantity": 50,
"category_id": 1,
"image_url": "https://example.com/iphone15.jpg"
}GET {{api_url}}/products
Headers:
Accept: application/json
Query Parameters (optional):
page: 1per_page: 15category_id: 1search: "iPhone"
GET {{api_url}}/search/products?q=iPhone
Headers:
Accept: application/json
POST {{api_url}}/cart/items
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"product_id": 1,
"quantity": 2
}GET {{api_url}}/cart
Headers:
Accept: application/json
Authorization: Bearer {{auth_token}}
POST {{api_url}}/orders
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"shipping_address": "123 Main St, City, State 12345",
"billing_address": "123 Main St, City, State 12345"
}GET {{api_url}}/my-orders
Headers:
Accept: application/json
Authorization: Bearer {{auth_token}}
POST {{api_url}}/tags
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"name": "Premium",
"slug": "premium"
}POST {{api_url}}/products/1/tags
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"tag_ids": [1, 2, 3]
}PUT {{api_url}}/orders/1/status
Headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
Body (JSON):
{
"status": "shipped"
}POST {{api_url}}/logout
Headers:
Accept: application/json
Authorization: Bearer {{auth_token}}
You can create a Postman collection with all these requests. Here's a sample collection structure:
{
"info": {
"name": "Ecommerce API",
"description": "Complete API testing collection for Laravel Ecommerce API"
},
"variable": [
{
"key": "base_url",
"value": "http://localhost:8000"
},
{
"key": "api_url",
"value": "{{base_url}}/api"
}
]
}- Register a new user
- Login with the user
- Browse products
- Add products to cart
- Create an order
- View order history
- Login as admin
- Create categories
- Create products
- Create tags and attach to products
- View all orders
- Update order statuses
Test these error scenarios:
- Unauthorized Access: Try accessing protected endpoints without token
- Invalid Data: Send malformed JSON or missing required fields
- Not Found: Request non-existent resources
- Validation Errors: Send invalid email formats, short passwords, etc.
Example error response:
{
"success": false,
"message": "Validation failed",
"errors": {
"email": ["The email field is required."],
"password": ["The password must be at least 8 characters."]
}
}200: Success (GET, PUT requests)201: Created (POST requests)204: No Content (DELETE requests)400: Bad Request (validation errors)401: Unauthorized (missing or invalid token)403: Forbidden (insufficient permissions)404: Not Found (resource doesn't exist)422: Unprocessable Entity (validation errors)500: Internal Server Error
Run the automated test suite with:
php artisan testFor specific test types:
# Run feature tests only
php artisan test --testsuite=Feature
# Run with coverage
php artisan test --coverage
# Run specific test file
php artisan test tests/Feature/AuthTest.phpThis project is open-sourced software licensed under the MIT license.