jandersongarcia/echostack

Simple BackEnd PHP

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

Type:project

pkg:composer/jandersongarcia/echostack

v1.0.6 2026-02-19 17:57 UTC

This package is auto-updated.

Last update: 2026-02-19 18:41:35 UTC


README

EchoStack Logo

Latest Version on Packagist Total Downloads

EchoStack – Lightweight PHP Microstack for REST APIs

EchoStack is a minimalist microstack designed for developers who want to build RESTful APIs in PHP with speed, clean structure, and low coupling. Rather than being a full-stack framework, EchoStack acts as a backend toolbox — delivering only the essential components needed for routing, validation, authentication, caching, logging, and integrations.

📘 Docs: start at ENV_SETUP_GUIDE.md and the docs/ folder:

  • docs/ENV.md (env vars)
  • docs/ROUTING.md (routing + per-route middleware)
  • docs/AUTH.md (headers + flows)
  • docs/CLI.md (composer scripts)
  • docs/DEPLOY.md (deploy checklist)

Start here (recommended order)

  1. ENV_SETUP_GUIDE.md – get it running + avoid common gotchas
  2. docs/AUTH.md – how requests are authenticated
  3. docs/ROUTING.md – how to add routes + middlewares

If you get stuck, check docs/DEPLOY.md (DocumentRoot, permissions, production flags).

📄 System Requirements

  • PHP >= 8.1

  • Composer >= 2.x

  • PostgreSQL 14+ (default) or MySQL 8+ / MariaDB

  • Redis (optional, for caching)

  • PHP Extensions:

    • pdo_pgsql (PostgreSQL)
    • pdo_mysql (MySQL/MariaDB)
    • mbstring
    • openssl
    • curl
    • json

✅ Key Features

  • Routing with AltoRouter

  • Lightweight ORM using Medoo

  • Data validation with Respect\Validation (via validators you call from your controllers/services)

  • Structured logging via Monolog

  • Authentication layers (middleware-driven):

    • API Key (X-API-KEY)
    • JWT (Bearer)
    • OAuth provider validation (middleware)
  • Flexible caching via Symfony Cache (Filesystem, Redis, APCu)

  • Native email support with PHPMailer

  • Real-time error alerts through Telegram

  • Request tracing with X-Request-Id

Validation in practice

EchoStack ships with Respect\Validation, but it does not auto-validate request bodies.

  • Generated modules create src/Validators/*Validator.php helpers.
  • Controllers/services should call validators explicitly and return a 422 response when validation fails.

If you want validation as a formal pipeline layer, implement a dedicated validation middleware and apply it per-route.

🛠️ Technologies Used

  • PHP 8.x
  • Medoo (PDO wrapper)
  • AltoRouter (Routing)
  • Monolog (Logging)
  • Respect\Validation (Validation)
  • Symfony HttpFoundation (Request/Response)
  • Symfony Console (CLI scripts)
  • Symfony Cache (Multi-driver caching)
  • Predis (Redis integration)
  • PHPMailer (SMTP email)
  • Firebase PHP-JWT (JWT support)
  • OAuth2 (Azure AD, Google, LinkedIn)
  • vlucas/phpdotenv (Environment config)

📁 Project Structure

project-root/
├── public/              # Web root (DocumentRoot) + Swagger UI (static)
├── src/                 # Application logic (controllers, utils, etc.) — PSR-4: App\
├── core/                # Kernel, services, dispatcher, OpenAPI bootstrap, scripts
├── routes/              # Route definitions (web.php includes swagger.php)
├── middleware/          # HTTP middlewares
├── bootstrap/           # App bootstrap
├── config/              # Configuration files
├── storage/             # Cache & logs (must be writable)
├── scripts/             # Utility scripts
├── docs/                # Usage documentation (ENV / AUTH / ROUTING / CLI / DEPLOY)
├── .env.example         # Environment template (copy to .env)
└── README.md

Note: the repo also includes an app/ directory mirroring some assets. Prefer public/ as the web root to keep /docs/ working consistently.

🗃 Database Initialization

Default schema and seed data:

core/Migration/auth-migrations.pgsql.sql
core/Migration/auth-migrations.mysql.sql

Which file is used depends on DB_DRIVER.

This creates basic auth tables: users, roles, user_tokens, password_resets.

Default user (dev)

  • Email: master@echostack.local
  • Password: master!123@

⚠️ Rotate/remove this user in real environments.

Automatic migration with Docker

If you're using Docker, set in .env:

AUTO_MIGRATE=true

After first run, set AUTO_MIGRATE=false.

📦 Install via Composer

composer create-project jandersongarcia/echostack echostack-example

🚀 Manual Installation

git clone https://github.com/jandersongarcia/EchoStack.git
cd EchoStack
composer install
cp .env.example .env
chmod -R 775 storage

Web server setup (important):

  • Set your DocumentRoot to public/
  • Enable mod_rewrite (Apache) and allow .htaccess (AllowOverride All)
  • Ensure storage/ is writable by the web server user

🚧 Docker Support

cp .env.example .env
# (recommended) edit DB_NAME / DB_USER / DB_PASS in .env BEFORE the first run

# Note: dotenv values cannot contain unquoted whitespace.
# If you edit comma-separated lists (e.g. CORS_ALLOW_METHODS / CORS_ALLOW_HEADERS),
# either remove spaces (GET,POST,...) or wrap the whole value in quotes.

docker compose up --build -d
docker compose exec app composer install

Windows (PowerShell) shortcut:

./scripts/up.ps1

To run with MySQL instead of PostgreSQL:

# set DB_DRIVER=mysql and DB_PORT=3306 in .env
docker compose -f docker-compose.mysql.yml up --build -d

Need help deciding which database to use?

  • See docs/ENV.mdChoosing the database (pgsql vs mysql).

Access:

  • App (SPA + Swagger UI): http://localhost:8080/
  • Swagger UI (static): http://localhost:8080/docs/
  • API base (default): http://localhost:8080/v1/

🚡 Request Lifecycle

  1. Request hits the web root (public/).
  2. public/.htaccess rewrites /v{n}/* to public/api/index.php.
  3. public/api/index.php loads bootstrap/app.php.
  4. bootstrap/app.php loads .env, configures CORS, sets router base path from API_BASE_PATH, and registers routes.
  5. Core\Dispatcher:
    • creates Symfony Request
    • injects / returns X-Request-Id
    • resolves route
    • loads per-route middlewares (or DEFAULT_MIDDLEWARES for legacy targets)
    • executes handler and normalizes the response

🔐 Authentication

Full details: docs/AUTH.md.

API Key (optional)

Set in .env:

API_KEY=your_key

Send header:

X-API-KEY: your_key

Generate a new key:

composer generate:key

JWT (Bearer)

Set in .env:

JWT_SECRET=change_me

Send header:

Authorization: Bearer <token>

Note: Bearer enforcement is controlled by AUTH_MODE (required|optional|off). If JWT_SECRET is empty, EchoStack can still validate Bearer tokens using the legacy DB token fallback.

🧭 Routing & Middlewares

Full details: docs/ROUTING.md.

Recommended route target style (explicit middlewares):

$router->map('GET', '/health', [
  'handler' => fn($request) => new JsonResponse(['ok' => true]),
  'middleware' => [],
]);

$router->map('GET', '/me', [
  'handler' => 'App\\Controllers\\UserController@me',
  'middleware' => ['auth'],
]);

📃 Swagger Documentation

Build OpenAPI JSON:

composer swagger:build

Output: core/OpenApi/openapi.json

Runtime endpoints

  • Swagger JSON: GET {API_BASE_PATH}{SWAGGER_ROUTE}/swagger.json

    • Example (default): GET /v1/docs/swagger.json
    • Requires: SWAGGER_ENABLED=true and APP_ENV != production
    • Optional: SWAGGER_ACCESS_KEY + X-Swagger-Key: <value>
  • Swagger UI (static): /docs/

    • The UI points to {API_BASE_PATH}{SWAGGER_ROUTE}/swagger.json via public/docs/swagger-initializer.js (adjust if you change API_BASE_PATH or SWAGGER_ROUTE)

🔎 Caching

Configured via .env:

CACHE_DRIVER=redis
REDIS_HOST=redis

Falls back to filesystem if not available.

🗒 Logging

  • Logs in storage/logs/
  • app.log: info+
  • error.log: error+

Test:

composer log:test

💬 Telegram Notifications

Enable in .env:

TELEGRAM_BOT_TOKEN=xxx
TELEGRAM_CHAT_ID=xxx
ERROR_NOTIFY_CATEGORIES=critical,error,alert

Test:

composer telegram:test

⚙️ Available Scripts

See docs/CLI.md.

📊 Changelog

Para ver mudanças por versão, use as Tags/Releases do GitHub (linha estável 1.x, atualmente v1.0.6).

Observação: referências a 2.x em trechos antigos da documentação devem ser tratadas como rascunho/planejamento até que existam tags públicas 2.x.