https://github.com/wmblw/search-engine-example
Example of implementing enterprise application practices on Laravel
https://github.com/wmblw/search-engine-example
abstract-factory-pattern adapter-pattern chain-of-responsibility circuit-breaker-pattern distributed-lock docker event-sourcing github-actions jwt-authentication laravel localization observer-pattern pest php race-conditions redis repository-pattern restful-api sanctum-authentication strategy-pattern
Last synced: 17 days ago
JSON representation
Example of implementing enterprise application practices on Laravel
- Host: GitHub
- URL: https://github.com/wmblw/search-engine-example
- Owner: wMBLw
- License: mit
- Created: 2025-09-30T18:11:01.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2025-10-03T09:33:56.000Z (7 months ago)
- Last Synced: 2025-10-03T10:27:45.836Z (7 months ago)
- Topics: abstract-factory-pattern, adapter-pattern, chain-of-responsibility, circuit-breaker-pattern, distributed-lock, docker, event-sourcing, github-actions, jwt-authentication, laravel, localization, observer-pattern, pest, php, race-conditions, redis, repository-pattern, restful-api, sanctum-authentication, strategy-pattern
- Language: PHP
- Homepage: https://mulkenburak.com
- Size: 250 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
#Search Engine Example
[](https://pestphp.com/)
[](https://www.php.net/)
[](https://laravel.com/)
[](https://www.docker.com/)
[](LICENSE)
---
## İçindekiler
- [Teknoloji Yığını](#-teknoloji-yığını)
- [Kurulum](#-kurulum)
- [API Dokümantasyonu](#-api-dokümantasyonu)
- [Kullanılan Tasarım Desenleri](#-kullanılan-tasarım-desenleri)
- [Proje Yapısı](#-proje-yapisi)
- [Konseptler](#-konseptler)
---
## Teknoloji Yığını
### Backend
- **PHP 8.2+**
- **Laravel 12.x**
- **MySQL 8.0** - Veritabanı
- **Redis 7.2** - Cache ve Queue
- **Guzzle HTTP** - API istekleri
### DevOps
- **Docker & Docker Compose** - Containerization
- **Nginx** - Web server
- **Supervisor** - Process management
### Testing & Quality
- **Pest PHP** - Testing framework
- **GitHub Actions** - CI/CD
### Monitoring & Debugging
- **Laravel Telescope** - Application debugging
- **Laravel Horizon** - Queue monitoring
---
## Kurulum
### Gereksinimler
- Docker ve Docker Compose
### Kurulum Adımları
**1. Projeyi klonlayın:**
```bash
git clone https://github.com/wMBLw/search-engine-example.git
cd search-engine-example/docker
```
**2. Environment dosyasını oluşturun:**
```bash
cp ../.env.example ../.env
```
> **Not:** .env.example dosyası hazır ayarlarla gelir, değişiklik yapmanıza gerek yoktur.
**3. Docker container'ları başlatın:**
```bash
docker compose --env-file ../.env up -d --build
```
**4. Tamamlandı**
Uygulama otomatik olarak:
- Bağımlılıkları yükler (composer, npm)
- Veritabanını oluşturur ve migrate eder
- Seed verilerini yükler
### Erişim Bilgileri
**API Base URL:** http://localhost/api
**Test Kullanıcısı:**
- Email: test@example.com
- Şifre: password
**Servisler:**
- **Web Application:** http://localhost
- **Telescope (Debug):** http://localhost/telescope
- **Horizon (Queue):** http://localhost/horizon
- **MySQL:** localhost:3306
- **Redis:** localhost:6379
---
## API Dokümantasyonu
### Postman Collection
Proje içinde hazır Postman collection ve environment dosyaları bulunmaktadır:
- postman/SearchEngineExample.postman_collection.json
- postman/SearchEngineExample.postman_environment.json
### Endpoints
#### Authentication
**1. Login**
```http
POST /api/login
Content-Type: application/json
{
"email": "test@example.com",
"password": "password"
}
```
**Response (200):**
```json
{
"data": {
"user": {
"id": 1,
"name": "Test User",
"email": "test@example.com"
},
"access_token": "1|xxxxxxxxxxxxx",
"refresh_token": "2|xxxxxxxxxxxxx",
"access_token_expires_at": "2025-10-03T13:00:00.000000Z",
"refresh_token_expires_at": "2025-11-02T12:00:00.000000Z"
}
}
```
**2. Refresh Token**
```http
POST /api/refresh-token
Authorization: Bearer {refresh_token}
```
**3. Get Logged In User**
```http
GET /api/user
Authorization: Bearer {access_token}
```
**4. Logout**
```http
GET /api/user/logout
Authorization: Bearer {access_token}
```
#### Search
**5. Search Contents**
```http
GET /api/search?keyword=laravel&type=article&sort_by=score&per_page=10&page=1
Authorization: Bearer {access_token}
```
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| keyword | string | No | - | Aranacak kelime (min: 2, max: 255) |
| type | string | No | - | İçerik tipi: video, article |
| sort_by | string | No | score | Sıralama: score, title, views, likes, published_at |
| sort_direction | string | No | desc | Sıralama yönü: asc, desc |
| per_page | integer | No | 20 | Sayfa başına kayıt (min: 1, max: 100) |
| page | integer | No | 1 | Sayfa numarası |
**Response (200):**
```json
{
"data": [
{
"id": 1,
"external_id": "ext-123",
"title": "Laravel 12 Yenilikleri",
"type": "article",
"views": 15000,
"likes": 1200,
"tags": ["laravel", "php", "framework"],
"published_at": "2025-10-01T10:00:00.000000Z",
"score": 125.75,
"provider": {
"id": 1,
"name": "Provider 1"
}
}
],
"meta": {
"current_page": 1,
"per_page": 10,
"total": 100
}
}
```
**6. Get Statistics**
```http
GET /api/search/statistics
Authorization: Bearer {access_token}
```
**Response (200):**
```json
{
"data": {
"total_contents": 1250,
"total_videos": 750,
"total_articles": 500,
"total_providers": 2,
"active_providers": 2
}
}
```
---
## Kullanılan Tasarım Desenleri
### 1.Abstract Factory Pattern
**Kullanım Alanı:** Provider Adapter'ları oluşturmak için
**Amaç:** Farklı veri formatlarını (JSON, XML) destekleyen provider adapter'larını dinamik olarak oluşturmak.
```
┌────────────────────────────────────────┐
│ ProviderAdapterFactory │
│ (Abstract Factory) │
└────────────────────────────────────────┘
│
│ creates
▼
┌────────────────────────────────────────┐
│ AbstractProviderAdapter │
│ (Abstract Product) │
└────────────────────────────────────────┘
△
│ implements
┌────────┴────────┐
│ │
┌───────────────┐ ┌──────────────┐
│ JsonProvider │ │ XmlProvider │
│ Adapter │ │ Adapter │
└───────────────┘ └──────────────┘
```
---
### 2.Adapter Pattern
**Kullanım Alanı:** Dış API'lerden gelen farklı formatları normalize etmek
**Amaç:** JSON ve XML formatındaki farklı veri yapılarını ortak bir formata dönüştürmek.
```
External APIs Adapters Application
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ JSON API │────────>│ JsonAdapter │─────>│ │
└──────────┘ └──────────────┘ │ Normalized │
┌──────────┐ ┌──────────────┐ │ Content │
│ XML API │────────>│ XmlAdapter │─────>│ DTO │
└──────────┘ └──────────────┘ └──────────────┘
```
---
### 3.Strategy Pattern
**Kullanım Alanı:** İçerik puanlama (scoring) algoritmaları
**Amaç:** Video ve Article içerikleri için farklı puanlama algoritmaları uygulamak.
```
┌────────────────────────────────┐
│ ScoringStrategyFactory │
└────────────────────────────────┘
│
│ creates
▼
┌────────────────────────────────┐
│ ScoringStrategyInterface │
└────────────────────────────────┘
△
│ implements
┌───────┴────────┐
│ │
┌───────────────┐ ┌────────────────┐
│ VideoScoring │ │ ArticleScoring │
│ Strategy │ │ Strategy │
└───────────────┘ └────────────────┘
```
---
### 4.Chain of Responsibility Pattern
**Kullanım Alanı:** Arama filtreleri
**Amaç:** Arama sorgusuna birden fazla filtreyi zincirleme şekilde uygulamak.
```
Search Query
│
▼
┌──────────────────┐
│ KeywordFilter │ → keyword varsa filtrele
└──────────────────┘
│
▼
┌──────────────────┐
│ ContentTypeFilter│ → type varsa filtrele
└──────────────────┘
│
▼
┌──────────────────┐
│ SortingFilter │ → sıralama uygula
└──────────────────┘
│
▼
Final Result
```
---
### 5.Circuit Breaker Pattern
**Kullanım Alanı:** Provider senkronizasyonu hata yönetimi
**Amaç:** Sürekli başarısız olan provider'ları geçici olarak devre dışı bırakmak.
```
┌─────────────────────────────────────────────────┐
│ Circuit Breaker States │
└─────────────────────────────────────────────────┘
┌──────────┐
│ CLOSED │ (Normal çalışma)
└──────────┘
│
│ Başarısız istekler artıyor
│ (consecutive_failures >= 3)
▼
┌──────────┐
│ OPEN │ (Devre dışı - 30 dakika)
└──────────┘
│
│ Timeout süresi doldu
▼
┌──────────┐
│ CLOSED │ (Tekrar aktif)
└──────────┘
```
**Veritabanı Yapısı:**
```sql
providers
├── consecutive_failures (int) -- Ardışık hata sayısı
└── disabled_until (timestamp) -- Devre dışı kalma süresi
```
---
### 6.Distributed Lock Pattern
**Kullanım Alanı:** Provider senkronizasyonu
**Amaç:** Aynı provider'ın aynı anda birden fazla process tarafından senkronize edilmesini önlemek.
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Process 1 │ │ Process 2 │ │ Process 3 │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
│ Lock Al │ Lock Almaya Çalış │ Lock Almaya Çalış
▼ ▼ ▼
┌────────────────────────────────────────────────────────────────┐
│ Redis Lock │
│ provider_sync_1: uuid-xxx-xxx │
└────────────────────────────────────────────────────────────────┘
│ │ │
│ ✅ Lock Alındı │ ❌ Bekle │ ❌ Bekle
▼ │ │
İşlem Yap │ │
│ │ │
│ Lock Serbest Bırak │ │
▼ ▼ ▼
✅ Tamamlandı ✅ Şimdi Alabilir ✅ Şimdi Alabilir
```
---
### 7.Observer Pattern
**Kullanım Alanı:** Content modeli değişikliklerinde cache yönetimi
---
### 8.Repository Pattern
**Kullanım Alanı:** Veri erişim katmanı
**Amaç:** Business logic ile veri erişim mantığını ayırmak.
---
### 9.Event-Driven Architecture
**Kullanım Alanı:** Kullanıcı login loglama
**Akış:**
```
Login → Event Dispatch → Listener → Queue Job → Database
```
---
### CI/CD Pipeline
GitHub Actions master branch'e PR açıldığında otomatik test çalıştırır:
```yaml
# .github/workflows/run-tests.yml
name: Run Pest Tests
on:
pull_request:
branches: [ master ]
jobs:
laravel-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/pest
```
---
## Proje Yapısı
```
search-engine-example/
│
├── app/
│ ├── Console/Commands/ # Artisan komutları
│ ├── Enums/ # Enum'lar
│ ├── Events/ # Event'ler
│ ├── Exceptions/ # Custom exception'lar
│ ├── Filters/ # Chain of Responsibility
│ ├── Http/
│ │ ├── Controllers/
│ │ ├── Requests/
│ │ └── Resources/
│ ├── Jobs/ # Queue jobs
│ ├── Listeners/ # Event listeners
│ ├── Models/
│ ├── Observers/ # Observer pattern
│ ├── Repositories/ # Repository pattern
│ └── Services/
│ ├── Auth/
│ ├── Content/ # Sync, Lock
│ ├── Providers/ # Adapter, Factory
│ └── Search/ # Strategy pattern
│
├── config/
├── database/
│ ├── factories/
│ ├── migrations/
│ └── seeders/
│
├── docker/
│ ├── docker-compose.yml
│ ├── Dockerfile
│ ├── entrypoint.sh
│ └── supervisord.conf
│
├── routes/
│ ├── api.php
│ └── web.php
│
├── tests/
│ ├── Feature/
│ └── Unit/
│
└── .github/workflows/ # CI/CD
└── run-tests.yml
```
---
## Mimari Diyagramlar
### Provider Sync Akışı
```
Artisan Command
│
▼
┌──────────────────────┐
│ContentSyncService │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ Distributed Lock │
│ Acquire Lock │──── ❌ Skip if locked
└──────────────────────┘
│
│ ✅ Lock Alındı
▼
┌──────────────────────┐
│ Provider Adapter │
│ Factory.make() │
└──────────────────────┘
│
├──→ JSON Adapter
└──→ XML Adapter
│
▼
┌──────────────────────┐
│ External API │
│ (JSON/XML Data) │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ NormalizedContentDTO │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ Content Model │
│ (Database) │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ ContentObserver │
│ clearStatisticsCache │
└──────────────────────┘
```
### Arama Akışı
```
User Request
│
▼
┌──────────────────────┐
│ SearchController │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ SearchService │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ SearchRepository │
└──────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ Pipeline (Chain of Responsibility) │
│ │
│ Query → KeywordFilter │
│ → ContentTypeFilter │
│ → SortingFilter │
└──────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ Database │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ ScoreCalculator │
│ (Strategy Pattern) │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ SearchResultDTO │
└──────────────────────┘
```
---
## Uygulanan Konseptler
### Tasarım Desenleri
- Abstract Factory Pattern
- Adapter Pattern
- Strategy Pattern
- Chain of Responsibility Pattern
- Circuit Breaker Pattern
- Observer Pattern
- Repository Pattern
- Factory Pattern
### Yazılım Prensipleri
- SOLID Prensipleri
- Clean Code
- KISS
- DRY
- Dependency Injection
### Mimari Konseptler
- Layered Architecture
- Event-Driven Architecture
- DTO
- Service Layer Pattern
- Distributed Lock
- Race Condition Prevention
- Circuit Breaker
### Laravel Özellikleri
- Sanctum Authentication (JWT)
- Eloquent ORM & Relationships
- Query Scopes (Global & Local)
- Model Observers
- Events & Listeners
- Queue Jobs (Redis)
- Laravel Horizon
- Laravel Telescope
- Service Providers
- Middleware
- Custom Artisan Commands
### Testing
- Pest PHP Testing Framework
- Unit Tests
- Feature Tests
---
## Önemli Komutlar
### Artisan Commands
```bash
# Seed data
php artisan db:seed
# Provider senkronizasyonu
php artisan providers:sync
```
### Docker Commands
```bash
# Container'ları başlat
docker compose --env-file ../.env up -d --build
# Container'ları durdur
docker compose down
```
---