webfiori / http
Basic library that can help in creating RESTful APIs using PHP.
Installs: 45 323
Dependents: 3
Suggesters: 0
Security: 0
Stars: 6
Watchers: 1
Forks: 0
Open Issues: 1
pkg:composer/webfiori/http
Requires
- php: >=7.0
- ext-json: *
- ext-mbstring: *
- webfiori/jsonx: 4.0.x
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.92
- phpunit/phpunit: ^10.0
- dev-main
- 5.0.0
- 4.0.0
- 3.6.1
- 3.6.0
- 3.5.1
- 3.5.0
- 3.4.1
- 3.4.0
- v3.3.15
- v3.3.14
- v3.3.13
- v3.3.12
- v3.3.11
- v3.3.10
- v3.3.9
- v3.3.8
- v3.3.7
- v3.3.6
- v3.3.5
- v3.3.4
- v3.3.3
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.20
- v3.2.19
- v3.2.18
- v3.2.17
- v3.2.16
- v3.2.15
- v3.2.14
- v3.2.13
- v3.2.12
- v3.2.11
- v3.2.10
- v3.2.9
- v3.2.8
- v3.2.7
- v3.2.6
- v3.2.5
- v3.2.4
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.x-dev
- v2.0.2
- v2.0.1
- v2.0.0
- v1.5.1
- v1.5.0
- v1.4.9
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- dev-release-please--branches--main
- dev-dev
- dev-docs
- dev-ci-updates
- dev-feat-attriputes
- dev-open-api-support
- dev-feat-csp
- dev-release-please--branches--master
- dev-refactoring
- dev-feat-add-test-headers
- dev-fix-get-uri
- dev-cache
- dev-updated-json-lib
- dev-rename-to-http
- dev-abstraction
- dev-json-support
This package is auto-updated.
Last update: 2025-12-30 15:59:20 UTC
README
A powerful and flexible PHP library for creating RESTful web APIs with built-in input filtering, data validation, and comprehensive HTTP utilities. The library provides a clean, object-oriented approach to building web services with automatic parameter validation, authentication support, and JSON response handling.
Table of Contents
Supported PHP Versions
| Build Status |
|---|
Key Features
- RESTful API Development: Full support for creating REST services with JSON request/response handling
- Automatic Input Validation: Built-in parameter validation with support for multiple data types
- Custom Filtering: Ability to create user-defined input filters and validation rules
- Authentication Support: Built-in support for various authentication schemes (Basic, Bearer, etc.)
- HTTP Method Support: Support for all standard HTTP methods (GET, POST, PUT, DELETE, etc.)
- Content Type Handling: Support for
application/json,application/x-www-form-urlencoded, andmultipart/form-data - Object Mapping: Automatic mapping of request parameters to PHP objects
- Comprehensive Testing: Built-in testing utilities with
APITestCaseclass - Error Handling: Structured error responses with appropriate HTTP status codes
- Stream Support: Custom input/output stream handling for advanced use cases
Installation
Using Composer (Recommended)
composer require webfiori/http
Manual Installation
Download the latest release from GitHub Releases and include the autoloader:
require_once 'path/to/webfiori-http/vendor/autoload.php';
Quick Start
Modern Approach with Attributes (Recommended)
PHP 8+ attributes provide a clean, declarative way to define web services:
<?php use WebFiori\Http\WebService; use WebFiori\Http\Annotations\RestController; use WebFiori\Http\Annotations\GetMapping; use WebFiori\Http\Annotations\PostMapping; use WebFiori\Http\Annotations\RequestParam; use WebFiori\Http\Annotations\ResponseBody; use WebFiori\Http\Annotations\AllowAnonymous; use WebFiori\Http\ParamType; #[RestController('hello', 'A simple greeting service')] class HelloService extends WebService { #[GetMapping] #[ResponseBody] #[AllowAnonymous] #[RequestParam('name', ParamType::STRING, true)] public function sayHello(?string $name): string { return $name ? "Hello, $name!" : "Hello, World!"; } #[PostMapping] #[ResponseBody] #[AllowAnonymous] #[RequestParam('message', ParamType::STRING)] public function customGreeting(string $message): array { return ['greeting' => $message, 'timestamp' => time()]; } }
Traditional Approach
For comparison, here's the traditional approach using constructor configuration:
<?php use WebFiori\Http\AbstractWebService; use WebFiori\Http\RequestMethod; use WebFiori\Http\ParamType; use WebFiori\Http\ParamOption; class HelloService extends AbstractWebService { public function __construct() { parent::__construct('hello'); $this->setRequestMethods([RequestMethod::GET]); $this->addParameters([ 'name' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => true ] ]); } public function isAuthorized() { return true; } public function processRequest() { $name = $this->getParamVal('name'); $this->sendResponse($name ? "Hello, $name!" : "Hello, World!"); } }
Both approaches work with WebServicesManager:
$manager = new WebServicesManager(); $manager->addService(new HelloService()); $manager->process();
Core Concepts
Terminology
| Term | Definition |
|---|---|
| Web Service | A single endpoint that implements a REST service, represented by AbstractWebService |
| Services Manager | An entity that manages multiple web services, represented by WebServicesManager |
| Request Parameter | A way to pass values from client to server, represented by RequestParameter |
| API Filter | A component that validates and sanitizes request parameters |
Architecture Overview
The library follows a service-oriented architecture:
- AbstractWebService: Base class for all web services
- WebServicesManager: Manages multiple services and handles request routing
- RequestParameter: Defines and validates individual parameters
- APIFilter: Handles parameter filtering and validation
- Request/Response: Utilities for handling HTTP requests and responses
Creating Web Services
Using Attributes (Recommended)
PHP 8+ attributes provide a modern, declarative approach:
<?php use WebFiori\Http\WebService; use WebFiori\Http\Annotations\RestController; use WebFiori\Http\Annotations\GetMapping; use WebFiori\Http\Annotations\PostMapping; use WebFiori\Http\Annotations\PutMapping; use WebFiori\Http\Annotations\DeleteMapping; use WebFiori\Http\Annotations\RequestParam; use WebFiori\Http\Annotations\ResponseBody; use WebFiori\Http\Annotations\RequiresAuth; use WebFiori\Http\ParamType; #[RestController('users', 'User management operations')] #[RequiresAuth] class UserService extends WebService { #[GetMapping] #[ResponseBody] #[RequestParam('id', ParamType::INT, true)] public function getUser(?int $id): array { return ['id' => $id ?? 1, 'name' => 'John Doe']; } #[PostMapping] #[ResponseBody] #[RequestParam('name', ParamType::STRING)] #[RequestParam('email', ParamType::EMAIL)] public function createUser(string $name, string $email): array { return ['id' => 2, 'name' => $name, 'email' => $email]; } #[PutMapping] #[ResponseBody] #[RequestParam('id', ParamType::INT)] #[RequestParam('name', ParamType::STRING)] public function updateUser(int $id, string $name): array { return ['id' => $id, 'name' => $name]; } #[DeleteMapping] #[ResponseBody] #[RequestParam('id', ParamType::INT)] public function deleteUser(int $id): array { return ['deleted' => $id]; } }
Traditional Class-Based Approach
Every web service must extend AbstractWebService and implement the processRequest() method:
<?php use WebFiori\Http\AbstractWebService; use WebFiori\Http\RequestMethod; class MyService extends AbstractWebService { public function __construct() { parent::__construct('my-service'); $this->setRequestMethods([RequestMethod::GET, RequestMethod::POST]); $this->setDescription('A sample web service'); } public function isAuthorized() { // Implement authorization logic return true; } public function processRequest() { // Implement service logic $this->sendResponse('Service executed successfully'); } }
Service Configuration
Setting Request Methods
// Single method $this->addRequestMethod(RequestMethod::POST); // Multiple methods $this->setRequestMethods([ RequestMethod::GET, RequestMethod::POST, RequestMethod::PUT ]);
Service Metadata
$this->setDescription('Creates a new user profile'); $this->setSince('1.2.0'); $this->addResponseDescription('Returns user profile data on success'); $this->addResponseDescription('Returns error message on failure');
Parameter Management
Parameter Types
The library supports various parameter types through ParamType:
ParamType::STRING // String values ParamType::INT // Integer values ParamType::DOUBLE // Float/double values ParamType::BOOL // Boolean values ParamType::EMAIL // Email addresses (validated) ParamType::URL // URLs (validated) ParamType::ARR // Arrays ParamType::JSON_OBJ // JSON objects
Adding Parameters
Simple Parameter Addition
use WebFiori\Http\RequestParameter; $param = new RequestParameter('username', ParamType::STRING); $this->addParameter($param);
Batch Parameter Addition
$this->addParameters([ 'username' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => false ], 'age' => [ ParamOption::TYPE => ParamType::INT, ParamOption::OPTIONAL => true, ParamOption::MIN => 18, ParamOption::MAX => 120, ParamOption::DEFAULT => 25 ], 'email' => [ ParamOption::TYPE => ParamType::EMAIL, ParamOption::OPTIONAL => false ] ]);
Parameter Options
Available options through ParamOption:
ParamOption::TYPE // Parameter data type ParamOption::OPTIONAL // Whether parameter is optional ParamOption::DEFAULT // Default value for optional parameters ParamOption::MIN // Minimum value (numeric types) ParamOption::MAX // Maximum value (numeric types) ParamOption::MIN_LENGTH // Minimum length (string types) ParamOption::MAX_LENGTH // Maximum length (string types) ParamOption::EMPTY // Allow empty strings ParamOption::FILTER // Custom filter function ParamOption::DESCRIPTION // Parameter description
Custom Validation
$this->addParameters([ 'password' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::MIN_LENGTH => 8, ParamOption::FILTER => function($original, $basic) { // Custom validation logic if (strlen($basic) < 8) { return APIFilter::INVALID; } // Additional password strength checks return $basic; } ] ]);
Retrieving Parameter Values
public function processRequest() { $username = $this->getParamVal('username'); $age = $this->getParamVal('age'); $email = $this->getParamVal('email'); // Get all inputs as array $allInputs = $this->getInputs(); }
Testing
Using APITestCase
<?php use WebFiori\Http\APITestCase; class MyServiceTest extends APITestCase { public function testGetRequest() { $manager = new WebServicesManager(); $manager->addService(new MyService()); $response = $this->getRequest($manager, 'my-service', [ 'param1' => 'value1', 'param2' => 'value2' ]); $this->assertJson($response); $this->assertContains('success', $response); } public function testPostRequest() { $manager = new WebServicesManager(); $manager->addService(new MyService()); $response = $this->postRequest($manager, 'my-service', [ 'name' => 'John Doe', 'email' => 'john@example.com' ]); $this->assertJson($response); } }
Examples
Complete CRUD Service Example
<?php use WebFiori\Http\WebService; use WebFiori\Http\Annotations\RestController; use WebFiori\Http\Annotations\GetMapping; use WebFiori\Http\Annotations\PostMapping; use WebFiori\Http\Annotations\PutMapping; use WebFiori\Http\Annotations\DeleteMapping; use WebFiori\Http\Annotations\RequestParam; use WebFiori\Http\Annotations\ResponseBody; use WebFiori\Http\Annotations\AllowAnonymous; use WebFiori\Http\ParamType; #[RestController('tasks', 'Task management service')] class TaskService extends WebService { #[GetMapping] #[ResponseBody] #[AllowAnonymous] public function getTasks(): array { return [ 'tasks' => [ ['id' => 1, 'title' => 'Task 1', 'completed' => false], ['id' => 2, 'title' => 'Task 2', 'completed' => true] ], 'count' => 2 ]; } #[PostMapping] #[ResponseBody] #[AllowAnonymous] #[RequestParam('title', ParamType::STRING)] #[RequestParam('description', ParamType::STRING, true)] public function createTask(string $title, ?string $description): array { return [ 'id' => 3, 'title' => $title, 'description' => $description ?: '', 'completed' => false ]; } #[PutMapping] #[ResponseBody] #[AllowAnonymous] #[RequestParam('id', ParamType::INT)] #[RequestParam('title', ParamType::STRING, true)] public function updateTask(int $id, ?string $title): array { return [ 'id' => $id, 'title' => $title, 'updated_at' => date('Y-m-d H:i:s') ]; } #[DeleteMapping] #[ResponseBody] #[AllowAnonymous] #[RequestParam('id', ParamType::INT)] public function deleteTask(int $id): array { return [ 'id' => $id, 'deleted_at' => date('Y-m-d H:i:s') ]; } }
For more examples, check the examples directory in this repository.
Key Classes Documentation
AbstractWebService- Base class for web servicesWebServicesManager- Services managementRequestParameter- Parameter definition and validationAPIFilter- Input filtering and validationRequest- HTTP request utilitiesResponse- HTTP response utilities
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Examples: Examples Directory
Changelog
See CHANGELOG.md for a list of changes and version history.