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
Requires
- altorouter/altorouter: ^2.0
- catfan/medoo: ^2.1
- firebase/php-jwt: ^6.11
- league/oauth2-google: ^4.0
- league/oauth2-linkedin: ^5.1
- monolog/monolog: ^3.0
- nyholm/psr7: ^1.8
- phpmailer/phpmailer: ^6.10
- predis/predis: ^3.0
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- respect/validation: ^2.2
- symfony/cache: ^7.3
- symfony/console: ^7.3
- symfony/http-foundation: ^7.0
- symfony/psr-http-message-bridge: ^7.3
- thenetworg/oauth2-azure: ^2.2
- vlucas/phpdotenv: ^5.6
Requires (Dev)
- zircote/swagger-php: 5.1
README
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.mdand thedocs/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)
ENV_SETUP_GUIDE.md– get it running + avoid common gotchasdocs/AUTH.md– how requests are authenticateddocs/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)
- API Key (
-
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.phphelpers. - Controllers/services should call validators explicitly and return a
422response 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. Preferpublic/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.md→ Choosing 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
- Request hits the web root (
public/). public/.htaccessrewrites/v{n}/*topublic/api/index.php.public/api/index.phploadsbootstrap/app.php.bootstrap/app.phploads.env, configures CORS, sets router base path fromAPI_BASE_PATH, and registers routes.Core\Dispatcher:- creates
Symfony Request - injects / returns
X-Request-Id - resolves route
- loads per-route middlewares (or
DEFAULT_MIDDLEWARESfor legacy targets) - executes handler and normalizes the response
- creates
🔐 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). IfJWT_SECRETis 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=trueandAPP_ENV != production - Optional:
SWAGGER_ACCESS_KEY+X-Swagger-Key: <value>
- Example (default):
-
Swagger UI (static):
/docs/- The UI points to
{API_BASE_PATH}{SWAGGER_ROUTE}/swagger.jsonviapublic/docs/swagger-initializer.js(adjust if you change API_BASE_PATH or SWAGGER_ROUTE)
- The UI points to
🔎 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.