Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ build/
dist/





92 changes: 91 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,97 @@

All notable changes to `EloquentHttpAdapter` will be documented in this file.

## Version 1.0
## Version 2.1.0

### Added
- **HttpModelInterface** - Interface for better architecture and testing
- **Custom exceptions** - HttpModelException for better error handling
- **Enhanced error handling** - Configurable error handling with custom exceptions
- **Response validation** - Better validation of API responses
- **Facade support** - HttpModel facade for convenient access
- **Comprehensive tests** - Test suite for HttpModel functionality
- **Enhanced configuration** - More configuration options for customization
- **Better documentation** - Updated examples and usage patterns

### Improved
- **Error handling** - More specific error messages and better exception handling
- **Response validation** - Validation of response format and structure
- **Configuration** - More granular configuration options
- **Testing** - Comprehensive test coverage
- **Architecture** - Interface-based design for better extensibility

### Fixed
- **Method visibility** - Fixed interface compliance issues
- **Error reporting** - Better error reporting and logging
- **Response handling** - Improved handling of invalid responses

## Version 2.0.0

### Breaking Changes
- **Removed InteractsWithHttp trait** - The trait has been completely removed
- **HttpModel is now the only approach** - All models must extend HttpModel
- **No backward compatibility** - Existing code using the trait will break

### Added
- **HttpModel abstract class** - Clean inheritance-based approach
- **Improved error handling** - More robust error management with proper validation
- **Enhanced configuration** - Comprehensive configuration options
- **Better input validation** - Safety checks for ID and response data
- **New methods** - `find()` and `findOrFail()` methods for single record retrieval
- **Configuration file** - Full configuration support with publishable config
- **Better testing support** - Easier to mock and test

### Fixed
- **Critical issue with trait method overriding** - Replaced trait with abstract class
- **Private method accessibility** - Made methods properly accessible for inheritance
- **JSON response validation** - Added checks for response structure
- **Infinite recursion in where parsing** - Added protection against circular references
- **Hardcoded pagination limits** - Made configurable via config file
- **Exception handling** - Improved error handling with proper logging
- **LIKE operator handling** - Fixed wildcard processing for LIKE queries

### Changed
- **Architecture** - Moved from trait-based to inheritance-based approach
- **Method visibility** - Changed private methods to protected for proper inheritance
- **Configuration** - Added comprehensive configuration system
- **Documentation** - Updated README with new usage patterns
- **Version numbering** - Major version bump due to breaking changes

### Removed
- **InteractsWithHttp trait** - Completely removed from the codebase
- **Legacy documentation** - Removed all references to the trait approach
- **Deprecated methods** - All trait-based methods removed

## Version 1.1.0

### Added
- **New HttpModel abstract class** - Replaces trait approach with better architecture
- **Improved error handling** - More robust error management with proper validation
- **Enhanced configuration** - Comprehensive configuration options
- **Better input validation** - Safety checks for ID and response data
- **New methods** - `find()` and `findOrFail()` methods for single record retrieval
- **Configuration file** - Full configuration support with publishable config
- **Backward compatibility** - Trait still works but is deprecated

### Fixed
- **Critical issue with trait method overriding** - Replaced trait with abstract class
- **Private method accessibility** - Made methods properly accessible for inheritance
- **JSON response validation** - Added checks for response structure
- **Infinite recursion in where parsing** - Added protection against circular references
- **Hardcoded pagination limits** - Made configurable via config file
- **Exception handling** - Improved error handling with proper logging
- **LIKE operator handling** - Fixed wildcard processing for LIKE queries

### Changed
- **Architecture** - Moved from trait-based to inheritance-based approach
- **Method visibility** - Changed private methods to protected for proper inheritance
- **Configuration** - Added comprehensive configuration system
- **Documentation** - Updated README with new usage patterns and migration guide

### Deprecated
- **InteractsWithHttp trait** - Use HttpModel instead (still works but deprecated)

## Version 1.0.3

### Added
- Everything
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"Iafilin\\EloquentHttpAdapter\\EloquentHttpAdapterServiceProvider"
],
"aliases": {
"EloquentHttpAdapter": "Iafilin\\EloquentHttpAdapter\\Facades\\EloquentHttpAdapter"
"HttpModel": "Iafilin\\EloquentHttpAdapter\\Facades\\HttpModel"
}
}
},
Expand Down
127 changes: 126 additions & 1 deletion config/eloquent-http-adapter.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,130 @@
<?php

return [
//
/*
|--------------------------------------------------------------------------
| Default HTTP Configuration
|--------------------------------------------------------------------------
|
| This option controls the default HTTP configuration for the package.
|
*/
'defaults' => [
'base_url' => '/api',
'timeout' => 30,
'retry_times' => 3,
'retry_milliseconds' => 1000,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
],

/*
|--------------------------------------------------------------------------
| Pagination Configuration
|--------------------------------------------------------------------------
|
| This option controls the pagination settings for HTTP models.
|
*/
'pagination' => [
'max_per_page' => 1000,
'default_per_page' => 15,
'page_name' => 'page',
'per_page_name' => 'per_page',
],

/*
|--------------------------------------------------------------------------
| Error Handling Configuration
|--------------------------------------------------------------------------
|
| This option controls how errors are handled by the package.
|
*/
'error_handling' => [
'log_errors' => true,
'throw_exceptions' => false,
'return_null_on_error' => true,
'log_level' => 'error',
],

/*
|--------------------------------------------------------------------------
| Query Builder Configuration
|--------------------------------------------------------------------------
|
| This option controls the query builder behavior.
|
*/
'query_builder' => [
'enable_eager_loading' => true,
'enable_sorting' => true,
'enable_filtering' => true,
'max_nested_depth' => 5,
'filter_prefix' => 'filter',
'sort_prefix' => 'sort',
'include_prefix' => 'include',
],

/*
|--------------------------------------------------------------------------
| Response Configuration
|--------------------------------------------------------------------------
|
| This option controls the response keys for HTTP models.
|
*/
'response' => [
'data_key' => 'data',
'total_key' => 'total',
'per_page_key' => 'per_page',
'current_page_key' => 'current_page',
],

/*
|--------------------------------------------------------------------------
| Response Validation Configuration
|--------------------------------------------------------------------------
|
| This option controls response validation settings.
|
*/
'response_validation' => [
'validate_response_format' => true,
'required_fields' => ['id'],
'optional_fields' => ['created_at', 'updated_at'],
],

/*
|--------------------------------------------------------------------------
| Cache Configuration
|--------------------------------------------------------------------------
|
| This option controls caching settings for HTTP requests.
|
*/
'cache' => [
'enabled' => false,
'ttl' => 300, // 5 minutes
'prefix' => 'http_model',
],

/*
|--------------------------------------------------------------------------
| Server-side Safelist Configuration
|--------------------------------------------------------------------------
|
| These options restrict which filters/sorts/includes can be applied on
| the API server to protect against over-fetching and unwanted access.
|
*/
'server' => [
'allowed_filters' => [],
'allowed_sorts' => [],
'allowed_includes' => [],
'between_columns' => [],
'infer_between' => true,
],
];
29 changes: 29 additions & 0 deletions examples/client/ModelExample.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Examples\Client;

use Iafilin\EloquentHttpAdapter\HttpModel;
use Illuminate\Http\Client\PendingRequest;

class Purchase extends HttpModel
{
protected ?string $apiEndpoint = 'https://api.example.com/purchases';

protected array $relationClassMap = [
'user' => \Examples\Client\User::class,
'items' => \Examples\Client\PurchaseItem::class,
];

public function httpClient(): PendingRequest
{
return \Http::asJson()
->baseUrl($this->apiEndpoint)
->withHeaders(['Authorization' => 'Bearer <token>'])
->timeout(30);
}
}

class User extends HttpModel {}
class PurchaseItem extends HttpModel {}


29 changes: 29 additions & 0 deletions examples/client/UsageExample.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Examples\Client;

require __DIR__ . '/ModelExample.php';

// List with filters, sorting, includes
$purchases = Purchase::query()
->where('status', 'approved') // filter[status]=approved
->where('created_at', '>=2024-01-01') // filter[created_at]=>=2024-01-01
->orderBy('created_at', 'desc') // sort=-created_at
->with(['user', 'items']) // include=user,items
->paginate(10); // page/per_page

// Single record with includes
$purchase = Purchase::with(['user','items'])->find(123);

// Lazy loading
$purchase->loadMissing('items');

// Create via API
$created = Purchase::create(['name' => 'New']);

// Update via API
if ($purchase) {
$purchase->update(['name' => 'Updated']);
}


11 changes: 11 additions & 0 deletions examples/server/Models/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
}


19 changes: 19 additions & 0 deletions examples/server/UserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Examples\Server;

use Iafilin\EloquentHttpAdapter\Server\HttpResponder;
use Iafilin\EloquentHttpAdapter\Server\QueryApplier;
use Illuminate\Http\Request;

class UserController
{
public function index(Request $request, QueryApplier $applier, HttpResponder $responder)
{
$builder = \App\Models\User::query();
$builder = $applier->apply($request, $builder);
return $responder->paginated($request, $builder);
}
}


8 changes: 8 additions & 0 deletions examples/server/routes_example.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

use Illuminate\Support\Facades\Route;
use Examples\Server\UserController;

Route::get('/users', [UserController::class, 'index']);


3 changes: 3 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@
<directory>src/</directory>
</whitelist>
</filter>
<php>
<ini name="error_reporting" value="E_ALL &amp; ~E_DEPRECATED &amp; ~E_USER_DEPRECATED"/>
</php>
</phpunit>
Loading