A modern, secure, and well-structured REST API built with vanilla PHP. This project implements a custom routing system inspired by modern frameworks, following a layered architecture pattern with clear separation of concerns between controllers, services, and models. It demonstrates practical approaches to error handling, authentication, and database operations in PHP.
- 🔐 JWT Authentication
- 🛡️ Secure Password Hashing
- 📦 Layered Architecture
- 🎯 MVC Pattern
- 🔄 RESTful Endpoints
- 🚦 Custom Routing System
- 📊 MySQL Database Integration
- ⚡ PDO for Database Operations
- 🎨 Modern Response Format
- 🛠️ Error Handling System
- 🐳 Docker Containerization
- PHP 8.2 (Docker: php:8.2-apache)
- MySQL 5.7 (Docker)
- phpMyAdmin (Docker)
- PDO
- JWT
- Composer (for dependency management)
The project uses Docker with the following services:
- Web Server: PHP 8.2 with Apache
- Database: MySQL 5.7
- Database Management: phpMyAdmin
- Network: Custom bridge network for service communication
The project implements a custom routing system inspired by modern PHP frameworks like Laravel. The core functionality is handled by the Core
class, which manages:
- Route dispatching
- Controller instantiation
- Method execution
- URL normalization
- Request/Response handling
Routes are defined using static methods, similar to Laravel's syntax:
Route::post('/users/create', 'UserController@store');
Route::get('/users/fetch', 'UserController@fetch');
The routing system supports:
- Dynamic route parameters (e.g.,
{id}
) - HTTP method validation
- Controller method mapping
- Automatic dependency injection
src/
├── Controllers/ # Application controllers
├── Core/ # Core system classes
├── Http/ # HTTP related classes
├── Models/ # Database models
├── Services/ # Business logic
└── Utils/ # Helper classes
- Controllers: Handle HTTP requests and responses
- Services: Contain business logic and data processing
- Models: Manage database interactions
- Http: Handle request/response and routing
- Utils: Provide helper functions and utilities
POST /users/create
- Create a new userPOST /users/login
- User authenticationGET /users/fetch
- Get user data (requires JWT)PUT /users/update
- Update user data (requires JWT)DELETE /users/{id}/delete
- Delete user (requires JWT)
- PHP 8.0 or higher
- MySQL Server
- Composer
- Web Server (Apache/Nginx)
- Clone the repository
git clone https://github.com/NatanR-dev/vanilla-php-rest-api.git
- Configure your database
// src/Models/Database.php
$pdo = new PDO("mysql:host=your_host;dbname=your_db", "your_user", "your_password");
- Create the database table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
This section provides a detailed technical overview of the project's architecture and implementation details for developers who want to understand or contribute to the codebase.
-
Routing System
// Route definition Route::post('/users/create', 'UserController@store'); // Route matching in Core class $pattern = '#^'. preg_replace('/{id}/', '([\w-]+)', $route['path']) .'$#'; if (preg_match($pattern, $url, $matches)) { // Route matched! }
-
Request Processing Pipeline
// Request body parsing $json = json_decode(file_get_contents('php://input'), true) ?? []; // Authorization header handling $headers = array_change_key_case(getallheaders(), CASE_LOWER); $authorizationPartials = explode(' ', $headers['authorization']);
-
Response System
// HTTP Response formatting $this->response->json([ 'error' => false, 'success' => true, 'data' => $data ], 200);
-
Connection Management
// PDO Connection $pdo = new PDO("mysql:host=db;dbname=app_db", "user", "user_password");
-
Error Handling
// MySQL Error Mapping match (true) { MySqlErrorResolver::isNoPermission($code) => ServiceResponse::error('Access denied for user.'), MySqlErrorResolver::isDatabaseNotFound($code) => ServiceResponse::error('Database does not exist.'), // ... other error cases }
-
JWT Implementation
// Token Generation $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']); $payload = json_encode($data); $signature = hash_hmac('sha256', $header . '.' . $payload, $secret, true); // Token Verification $tokenPartials = explode('.', $jwt); if ($signature !== self::signature($header, $payload)) return false;
-
Password Security
// Password Hashing $hashedPassword = password_hash($password, PASSWORD_DEFAULT); // Password Verification if(!password_verify($password, $user['password'])) return false;
-
Standard Response Format
// Success Response return [ 'error' => false, 'success' => true, 'message' => $message, 'data' => $data ]; // Error Response return [ 'error' => true, 'success' => false, 'message' => $message ];
-
Data Validation
// Field Validation foreach($fields as $field => $value) { if (empty(trim($value))) { throw new \Exception("The field $field is required."); } }
-
Service Definitions
services: web: build: context: . dockerfile: Dockerfile ports: - "8080:80" db: image: mysql:5.7 environment: MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER}
-
PHP Configuration
FROM php:8.2-apache RUN docker-php-ext-install pdo pdo_mysql RUN a2enmod rewrite
You can test all endpoints using the included REST Client file. The project comes with a pre-configured Request.http
file in the src/Utils/RestClient
directory. This file contains all the necessary requests to test the API endpoints.
To use it:
- Install the "REST Client" extension in VS Code
- Open the
Request.http
file - Click on "Send Request" above any request to test it
- For authenticated endpoints, make sure to update the JWT token in the authorization header
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
Uma API REST moderna, segura e bem estruturada construída com PHP puro. Este projeto implementa um sistema de rotas personalizado inspirado em frameworks modernos, seguindo um padrão de arquitetura em camadas com clara separação de responsabilidades entre controllers, services e models. Demonstra abordagens práticas para tratamento de erros, autenticação e operações com banco de dados em PHP.
- 🔐 Autenticação JWT
- 🛡️ Hash Seguro de Senhas
- 📦 Arquitetura em Camadas
- 🎯 Padrão MVC
- 🔄 Endpoints RESTful
- 🚦 Sistema de Rotas Personalizado
- 📊 Integração com MySQL
- ⚡ PDO para Operações no Banco
- 🎨 Formato Moderno de Resposta
- 🛠️ Sistema de Tratamento de Erros
- 🐳 Containerização com Docker
- PHP 8.2 (Docker: php:8.2-apache)
- MySQL 5.7 (Docker)
- phpMyAdmin (Docker)
- PDO
- JWT
- Composer (para gerenciamento de dependências)
O projeto utiliza Docker com os seguintes serviços:
- Servidor Web: PHP 8.2 com Apache
- Banco de Dados: MySQL 5.7
- Gerenciamento do Banco: phpMyAdmin
- Rede: Rede bridge personalizada para comunicação entre serviços
O projeto implementa um sistema de rotas personalizado inspirado em frameworks PHP modernos como Laravel. A funcionalidade principal é gerenciada pela classe Core
, que controla:
- Despacho de rotas
- Instanciação de controllers
- Execução de métodos
- Normalização de URLs
- Manipulação de Request/Response
As rotas são definidas usando métodos estáticos, similar à sintaxe do Laravel:
Route::post('/users/create', 'UserController@store');
Route::get('/users/fetch', 'UserController@fetch');
O sistema de rotas suporta:
- Parâmetros dinâmicos (ex:
{id}
) - Validação de métodos HTTP
- Mapeamento de métodos do controller
- Injeção automática de dependências
src/
├── Controllers/ # Controllers da aplicação
├── Core/ # Classes do sistema core
├── Http/ # Classes relacionadas a HTTP
├── Models/ # Modelos do banco de dados
├── Services/ # Lógica de negócios
└── Utils/ # Classes auxiliares
- Controllers: Gerenciam requisições e respostas HTTP
- Services: Contêm lógica de negócios e processamento de dados
- Models: Gerenciam interações com o banco de dados
- Http: Manipulam request/response e roteamento
- Utils: Fornecem funções e utilitários auxiliares
POST /users/create
- Criar novo usuárioPOST /users/login
- Autenticação de usuárioGET /users/fetch
- Obter dados do usuário (requer JWT)PUT /users/update
- Atualizar dados do usuário (requer JWT)DELETE /users/{id}/delete
- Deletar usuário (requer JWT)
- PHP 8.0 ou superior
- Servidor MySQL
- Composer
- Servidor Web (Apache/Nginx)
- Clone o repositório
git clone https://github.com/NatanR-dev/vanilla-php-rest-api.git
- Configure seu banco de dados
// src/Models/Database.php
$pdo = new PDO("mysql:host=seu_host;dbname=seu_db", "seu_usuario", "sua_senha");
- Crie a tabela do banco de dados
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Esta seção fornece uma visão técnica detalhada da arquitetura do projeto e detalhes de implementação para desenvolvedores que desejam entender ou contribuir com o código.
-
Sistema de Rotas
// Definição de rota Route::post('/users/create', 'UserController@store'); // Correspondência de rota na classe Core $pattern = '#^'. preg_replace('/{id}/', '([\w-]+)', $route['path']) .'$#'; if (preg_match($pattern, $url, $matches)) { // Rota encontrada! }
-
Pipeline de Processamento de Requisições
// Parsing do corpo da requisição $json = json_decode(file_get_contents('php://input'), true) ?? []; // Manipulação do header de autorização $headers = array_change_key_case(getallheaders(), CASE_LOWER); $authorizationPartials = explode(' ', $headers['authorization']);
-
Sistema de Resposta
// Formatação da resposta HTTP $this->response->json([ 'error' => false, 'success' => true, 'data' => $data ], 200);
-
Gerenciamento de Conexão
// Conexão PDO $pdo = new PDO("mysql:host=db;dbname=app_db", "user", "user_password");
-
Tratamento de Erros
// Mapeamento de Erros MySQL match (true) { MySqlErrorResolver::isNoPermission($code) => ServiceResponse::error('Acesso negado para o usuário.'), MySqlErrorResolver::isDatabaseNotFound($code) => ServiceResponse::error('Banco de dados não existe.'), // ... outros casos de erro }
-
Implementação JWT
// Geração de Token $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']); $payload = json_encode($data); $signature = hash_hmac('sha256', $header . '.' . $payload, $secret, true); // Verificação de Token $tokenPartials = explode('.', $jwt); if ($signature !== self::signature($header, $payload)) return false;
-
Segurança de Senha
// Hash de Senha $hashedPassword = password_hash($password, PASSWORD_DEFAULT); // Verificação de Senha if(!password_verify($password, $user['password'])) return false;
-
Formato Padrão de Resposta
// Resposta de Sucesso return [ 'error' => false, 'success' => true, 'message' => $message, 'data' => $data ]; // Resposta de Erro return [ 'error' => true, 'success' => false, 'message' => $message ];
-
Validação de Dados
// Validação de Campos foreach($fields as $field => $value) { if (empty(trim($value))) { throw new \Exception("O campo $field é obrigatório."); } }
-
Definições de Serviço
services: web: build: context: . dockerfile: Dockerfile ports: - "8080:80" db: image: mysql:5.7 environment: MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER}
-
Configuração PHP
FROM php:8.2-apache RUN docker-php-ext-install pdo pdo_mysql RUN a2enmod rewrite
Você pode testar todos os endpoints usando o arquivo REST Client incluído. O projeto vem com um arquivo Request.http
pré-configurado no diretório src/Utils/RestClient
. Este arquivo contém todas as requisições necessárias para testar os endpoints da API.
Para usar:
- Instale a extensão "REST Client" no VS Code
- Abra o arquivo
Request.http
- Clique em "Send Request" acima de qualquer requisição para testá-la
- Para endpoints autenticados, certifique-se de atualizar o token JWT no cabeçalho de autorização
Contribuições são bem-vindas! Sinta-se à vontade para enviar um Pull Request.
Este projeto está licenciado sob a Licença MIT - veja o arquivo LICENSE para detalhes.