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 Laravel Package

boson-php/uri-factory

PSR-17 URI factory for Boson PHP. Create and normalize URIs for Boson apps and WebView navigation, with simple Composer installation and docs integrated into the Boson ecosystem. PHP 8.4+ and MIT-licensed.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:
    composer require boson-php/uri-factory
    
  2. Basic Usage: Create a factory class (e.g., app/UriFactories/UserUriFactory.php):
    use Boson\UriFactory\UriFactory;
    
    class UserUriFactory extends UriFactory
    {
        public function profile(int $id): string
        {
            return $this->path("users/{$id}/profile");
        }
    }
    
  3. Register the Factory: Bind it in a service provider (e.g., AppServiceProvider):
    $this->app->singleton(UserUriFactory::class, function ($app) {
        return new UserUriFactory(config('app.url'));
    });
    
  4. First Use Case: Generate a URI in a controller:
    use App\UriFactories\UserUriFactory;
    
    class UserController extends Controller
    {
        public function show(UserUriFactory $factory, int $id)
        {
            $profileUrl = $factory->profile($id);
            return redirect($profileUrl);
        }
    }
    

Where to Look First

  • README.md: For installation and basic examples.
  • src/UriFactory.php: Core class to extend for custom factories.
  • tests/: Example test cases for validation and edge cases.
  • Boson Docs: For advanced features like schemes-api (e.g., custom URI schemes like app://).

Implementation Patterns

Usage Patterns

1. Factory Composition

Break down URI generation into domain-specific factories:

// API Factory
class ApiUriFactory extends UriFactory
{
    public function usersIndex(): string
    {
        return $this->path('api/v1/users');
    }
}

// Web Factory
class WebUriFactory extends UriFactory
{
    public function dashboard(): string
    {
        return $this->path('dashboard');
    }
}

Benefit: Isolate URI logic by feature (e.g., API vs. web routes).

2. Dynamic Segments with Validation

Use PHP 8.4’s named arguments and type hints:

public function product(int $id, ?string $variant = null): string
{
    $path = "products/{$id}";
    if ($variant) {
        $path .= "/variants/{$variant}";
    }
    return $this->path($path);
}

Call it:

$factory->product(123, 'premium'); // /products/123/variants/premium

3. Query Parameters

Leverage the factory’s built-in query builder:

public function search(string $query, int $page = 1): string
{
    return $this->path('search')
        ->withQuery([
            'q' => $query,
            'page' => $page,
        ]);
}

Output: /search?q=laptop&page=2

4. Integration with Laravel Routes

Generate route URIs without hardcoding:

public function generateRouteUri(string $name, array $params = []): string
{
    $uri = route($name, $params);
    return $this->uri($uri); // Wrap in factory for consistency
}

5. Context-Aware URIs

Inject context (e.g., tenant, locale) into factories:

class TenantAwareUriFactory extends UriFactory
{
    public function __construct(string $baseUrl, public string $tenantId)
    {
        parent::__construct($baseUrl);
    }

    public function tenantDashboard(): string
    {
        return $this->path("tenants/{$this->tenantId}/dashboard");
    }
}

Workflows

API Client Integration

Use factories to construct API endpoints dynamically:

class ApiClient
{
    public function __construct(private ApiUriFactory $factory) {}

    public function fetchUser(int $id)
    {
        $url = $this->factory->usersShow($id);
        return Http::get($url);
    }
}

Email Verification Links

Generate time-limited, signed URIs:

public function verificationLink(string $token): string
{
    return $this->path("verify-email/{$token}")
        ->withQuery(['expires' => now()->addHours(24)->timestamp]);
}

SEO Canonical URLs

Standardize canonical paths:

public function canonicalProduct(int $id): string
{
    return $this->path("products/{$id}")
        ->withQuery(['canonical' => true]);
}

Integration Tips

  1. Laravel Facade: Create a facade for cleaner syntax:

    // app/Facades/Uri.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    class Uri extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return 'uri.factory';
        }
    }
    

    Usage:

    Uri::product(123); // Instead of $factory->product(123)
    
  2. Configuration: Centralize base URLs in config/uri.php:

    return [
        'api' => env('API_URL', 'https://api.example.com'),
        'web' => env('APP_URL', 'https://example.com'),
    ];
    

    Factory:

    $factory = new UriFactory(config('uri.api'));
    
  3. Testing: Mock factories in tests:

    $factory = Mockery::mock(UserUriFactory::class);
    $factory->shouldReceive('profile')
        ->with(123)
        ->andReturn('/users/123/profile');
    
    $this->app->instance(UserUriFactory::class, $factory);
    
  4. Blade Directives: Add a Blade directive for inline URI generation:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('uri', function ($expression) {
        return "<?php echo app('uri.factory')->{$expression}; ?>";
    });
    

    Usage:

    <a href="{{ uri('dashboard') }}">Dashboard</a>
    

Gotchas and Tips

Pitfalls

  1. Double Encoding:

    • Issue: Query parameters may get double-encoded (e.g., %252F instead of /).
    • Fix: Use rawurlencode() or the factory’s built-in query builder:
      $this->withQuery(['search' => 'café']); // Handles encoding
      
  2. Path Collisions:

    • Issue: Overlapping path segments (e.g., /users/{id}/posts vs. /users/posts).
    • Fix: Use explicit path prefixes or validation:
      public function posts(int $userId): string
      {
          return $this->path("users/{$userId}/posts");
      }
      
  3. Laravel Route Cache:

    • Issue: Generated URIs may not respect Laravel’s route cache.
    • Fix: Clear cache after adding new routes:
      php artisan route:clear
      
  4. Case Sensitivity:

    • Issue: Linux servers treat /Users and /users as different paths.
    • Fix: Normalize paths in factories:
      return $this->path(strtolower("Users/{$id}"));
      
  5. Middleware Bypass:

    • Issue: Factories generate raw URIs that skip middleware (e.g., auth, CORS).
    • Fix: Use route() for internal routes:
      public function adminDashboard(): string
      {
          return route('admin.dashboard'); // Respects middleware
      }
      

Debugging

  1. Inspect Generated URIs:

    $uri = $factory->profile(123);
    dd($uri); // Debug the output
    
  2. Enable Query Logging: Add a debug method to factories:

    public function debug(): void
    {
        \Log::debug('URI Construction', [
            'path' => $this->path,
            'query' => $this->query,
            'base' => $this->baseUrl,
        ]);
    }
    
  3. Validate Against Laravel’s url():

    $factoryUri = $factory->dashboard();
    $laravelUri = url('/dashboard');
    assert($factoryUri === $laravelUri, "URIs must match!");
    

Config Quirks

  1. Base URL Overrides:

    • Issue: Hardcoded base URLs in factories.
    • Fix: Use Laravel’s config or environment variables:
      $factory = new UriFactory(config('app.url'));
      
  2. **Scheme

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