Back to Projects

Case Study

Bazar

Laravel 10 classifieds marketplace from the FreeLancer/bazar_P tree (same project as bazar_p on case-insensitive systems): Blade storefront with Laravel UI authentication, deep category navigation (sub through sub4), listings and product detail pages, mazad (auction listing) browsing, and an `/admin` dashboard for countries, cities, nested taxonomies, advertisements, sliders, contacts, and notifications. Parallel mobile JSON API under `/api` split into `guest-api.php` (login, register, password reset, catalog, home search, advertisements by geography) and `auth-api.php` (token-guarded profile, favourites, balance, post or list user ads, Firebase device token) with shared `lang` and `InitRequest` middleware.

Laravel 10PHPMySQLREST APILaravel UIMarketplace
Dual web + APIToken API authDeep categoriesAdmin CRUD
Bazar cover

Impact

One Laravel codebase the business could operate: staff manage taxonomy and ads in `/admin`, sellers use web or app against the same core tables.

Problem

A classifieds product has to serve both casual web visitors and mobile apps without duplicating business rules: category trees, listing quality, user balances, and staff moderation must stay consistent whether the client is Blade or JSON.

Solution

`RouteServiceProvider` wires four concerns: authenticated API controllers (`routes/auth-api.php` behind `auth:api` and the `api` token guard), public API controllers (`routes/guest-api.php`), an admin namespace under prefix `admin` with `admin` middleware, and the main `routes/web.php` site plus `Auth::routes()` from Laravel UI. Controllers stay namespaced under `App\Http\Controllers\Api`, `Admin`, and `Site` so web, admin, and mobile surfaces share the same models and validation.

Highlighted implementation

Route groups (RouteServiceProvider)

PHP
$this->routes(function () {
    Route::middleware(['api', 'auth:api', 'lang', 'InitRequest'])
        ->prefix('api')
        ->namespace($this->Api_namespace)
        ->group(base_path('routes/auth-api.php'));

    Route::middleware(['api', 'lang', 'InitRequest'])
        ->prefix('api')
        ->namespace($this->Api_namespace)
        ->group(base_path('routes/guest-api.php'));

    Route::middleware(['web', 'admin', 'lang'])
        ->prefix('admin')
        ->namespace($this->Admin_namespace)
        ->group(base_path('routes/admin.php'));

    Route::middleware(['web', 'site', 'lang'])
        ->namespace($this->Site_namespace)
        ->group(base_path('routes/site.php'));

    Route::middleware(['web', 'lang'])
        ->namespace('App\Http\Controllers')
        ->group(base_path('routes/web.php'));
});

Testing & quality

PHPUnit 10 in the project for automated checks where written; manual passes on add-listing, search, and admin taxonomy edits after Laravel upgrades.

Architecture

API Structure

Guest API uses POST endpoints for home, search, hierarchical categories, and `Advertisement` queries (country, city, single ad, offers). Authenticated API posts cover profile updates, favourites, user advertisements, notifications, and Firebase token updates. CORS config includes `api/*` paths for mobile origins.

Data Flow

Listing publish or edit flows through form or API controllers into advertisement rows tied to category and geography keys; admin CRUD updates taxonomy and homepage sliders that both web and API readers consume on next request.

Backend Decisions

Chose Laravel’s built-in `token` API guard instead of bolting on Passport for this scope; centralized `InitRequest` on API groups for shared mobile headers or context; kept admin routes prefix-isolated from public URLs to reduce accidental exposure.

Bazar architecture diagram
High-level diagram of web dashboard, REST API, Laravel layers, and MySQL.

Challenges

Very deep category trees (four sub-levels) complicate admin AJAX endpoints and mobile payloads—keeping N+1 queries under control matters on listing grids. Web and API must agree on soft-deletes or visibility flags so an item hidden in admin does not still appear in cached mobile responses.

Technical Decisions

Laravel 10 baseline with `laravel/ui` for rapid auth scaffolding and `laravelcollective/html` where forms benefit from helpers; Guzzle available for outbound HTTP when integrations land; PHPUnit 10 for regression safety on critical paths.