Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Uri Factory Contracts Laravel Package

boson-php/uri-factory-contracts

Lightweight PHP 8.4+ contracts for URI factory implementations used in the Boson ecosystem. Install via Composer and implement the interfaces to standardize URI creation across packages and applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package

    composer require boson-php/uri-factory-contracts
    

    No additional configuration is required for contracts alone.

  2. First Use Case: Define a URI Factory Contract Create a custom contract extending the base interface (e.g., app/Contracts/UriFactory.php):

    use Boson\UriFactoryContracts\Contracts\UriFactory as BaseUriFactory;
    
    interface UriFactory extends BaseUriFactory {
        public function createApiUri(string $path, array $params = []): string;
    }
    
  3. Implement the Contract with Laravel’s Url Create a concrete implementation (e.g., app/Services/LaravelUriFactory.php):

    use Boson\UriFactoryContracts\Contracts\UriFactory;
    use Illuminate\Support\Facades\Url;
    
    class LaravelUriFactory implements UriFactory {
        public function create(string $path, array $params = []): string {
            return Url::to($path, $params);
        }
    
        public function createApiUri(string $path, array $params = []): string {
            return $this->create("/api/v1/{$path}", $params);
        }
    }
    
  4. Bind the Implementation Register the factory in AppServiceProvider:

    public function register() {
        $this->app->singleton(
            \App\Contracts\UriFactory::class,
            \App\Services\LaravelUriFactory::class
        );
    }
    
  5. Usage in Controllers/Jobs Inject the factory via constructor and use it:

    use App\Contracts\UriFactory;
    
    class UserController {
        public function __construct(private UriFactory $uriFactory) {}
    
        public function show(User $user) {
            $userUri = $this->uriFactory->createApiUri("users/{$user->id}");
            return response()->json(['uri' => $userUri]);
        }
    }
    

Implementation Patterns

1. Dependency Injection Workflow

  • Use Case: Standardize URI generation across controllers, jobs, and services.
  • Pattern:
    // Define contract
    interface ApiUriFactory extends \Boson\UriFactoryContracts\Contracts\UriFactory {
        public function createAdminUri(string $path, array $params = []): string;
    }
    
    // Implement with Laravel’s Route facade
    class RouteApiUriFactory implements ApiUriFactory {
        public function create(string $path, array $params = []): string {
            return route('api.' . $path, $params);
        }
    
        public function createAdminUri(string $path, array $params = []): string {
            return $this->create("admin.{$path}", $params);
        }
    }
    
    // Bind in service provider
    $this->app->bind(
        \App\Contracts\ApiUriFactory::class,
        \App\Services\RouteApiUriFactory::class
    );
    
    // Inject and use
    class AdminController {
        public function __construct(private ApiUriFactory $uriFactory) {}
    
        public function index() {
            $adminUri = $this->uriFactory->createAdminUri('dashboard');
            // ...
        }
    }
    

2. Dynamic Route Parameter Handling

  • Use Case: Generate URIs with dynamic segments (e.g., /users/{id}).
  • Pattern:
    class DynamicUriFactory implements \Boson\UriFactoryContracts\Contracts\UriFactory {
        public function create(string $path, array $params = []): string {
            return route('api.' . $path, $params);
        }
    }
    
    // Usage in a job
    class SendWelcomeEmail implements ShouldQueue {
        public function __construct(private DynamicUriFactory $uriFactory) {}
    
        public function handle() {
            $userUri = $this->uriFactory->create('users.profile', ['id' => 123]);
            Mail::to('user@example.com')->send(new WelcomeEmail($userUri));
        }
    }
    

3. Testing Doubles

  • Use Case: Mock URIs in unit tests.
  • Pattern:
    // Test
    $mockFactory = Mockery::mock(\Boson\UriFactoryContracts\Contracts\UriFactory::class);
    $mockFactory->shouldReceive('create')
                ->with('users.show', ['id' => 1])
                ->andReturn('/users/1');
    
    $controller = new UserController($mockFactory);
    $response = $controller->show(new User());
    $this->assertEquals('/users/1', $response->original['uri']);
    

4. Middleware Integration

  • Use Case: Modify URIs based on request context (e.g., locale, tenant).
  • Pattern:
    class LocalizedUriFactory implements \Boson\UriFactoryContracts\Contracts\UriFactory {
        public function __construct(private \Boson\UriFactoryContracts\Contracts\UriFactory $decorated) {}
    
        public function create(string $path, array $params = []): string {
            $locale = app()->getLocale();
            return $this->decorated->create("{$locale}/{$path}", $params);
        }
    }
    
    // Bind in service provider
    $this->app->bind(
        \App\Contracts\UriFactory::class,
        fn($app) => new LocalizedUriFactory($app->make(\Boson\UriFactoryContracts\Contracts\UriFactory::class))
    );
    

5. Cross-Service Communication

  • Use Case: Generate URIs for internal API calls in a microservices architecture.
  • Pattern:
    class ServiceUriFactory implements \Boson\UriFactoryContracts\Contracts\UriFactory {
        private string $baseUrl;
    
        public function __construct() {
            $this->baseUrl = config('services.auth.base_uri');
        }
    
        public function create(string $path, array $params = []): string {
            return "{$this->baseUrl}/{$path}" . http_build_query($params);
        }
    }
    
    // Usage in a service client
    class AuthServiceClient {
        public function __construct(private ServiceUriFactory $uriFactory) {}
    
        public function getUserToken(string $email) {
            $uri = $this->uriFactory->create('auth/login', ['email' => $email]);
            return Http::post($uri, ['password' => '...']);
        }
    }
    

6. Query String Manipulation

  • Use Case: Append or modify query strings programmatically.
  • Pattern:
    class QueryUriFactory implements \Boson\UriFactoryContracts\Contracts\UriFactory {
        public function __construct(private \Boson\UriFactoryContracts\Contracts\UriFactory $decorated) {}
    
        public function create(string $path, array $params = []): string {
            $uri = $this->decorated->create($path);
            parse_str(parse_url($uri, PHP_URL_QUERY) ?? '', $query);
            $query = array_merge($query, $params);
            return str_replace(
                parse_url($uri, PHP_URL_QUERY),
                http_build_query($query),
                $uri
            );
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Over-Abstraction

    • Issue: Adding unnecessary layers for simple use cases (e.g., static Url::to() calls).
    • Fix: Use the factory only for dynamic, reusable, or cross-cutting URI logic.
  2. Route Cache Invalidation

    • Issue: If using route() in the factory, changes to route definitions may not reflect until the route cache is cleared.
    • Fix: Clear the route cache after defining routes:
      php artisan route:clear
      
  3. Circular Dependencies

    • Issue: Factories depending on other factories can create tight coupling.
    • Fix: Use dependency inversion (e.g., pass dependencies via constructor).
  4. PHP 8.4+ Requirement

    • Issue: Laravel 9+ supports PHP 8.1+, but this package requires PHP 8.4+.
    • Fix: Upgrade PHP or use a polyfill (if available).
  5. Missing URI Validation

    • Issue: Factories may generate invalid URIs (e.g., missing slashes, malformed paths).
    • Fix: Add validation in the factory:
      public function create(string $path, array $params = []): string {
          $path = ltrim($path, '/');
          return Url::to("/{$path}", $params);
      }
      
  6. Performance Overhead

    • Issue: Overly complex factories (e.g., with caching or middleware) may slow down URI generation.
    • Fix: Benchmark and optimize critical paths.

Debugging Tips

  1. Log URI Generation Add logging to trace URI creation:

    public function create(string $path, array $params = []): string {
        \Log::debug('URI created', ['path' => $path, 'params' => $params]);
        return Url::to($path, $params);
    }
    
  2. Use dd() for Inspection Temporarily dump factory outputs to debug:

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky