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

guzzlehttp/uri-template

RFC 6570 URI Template expansion for PHP. Build URLs by substituting variables into templates, handling reserved characters, query strings, and fragments. Lightweight Guzzle component installable via Composer, with tests and changelog included.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require guzzlehttp/uri-template
    

    Add to composer.json under require if not using Composer globally.

  2. First Use Case: Expand a URI template with variables:

    use GuzzleHttp\UriTemplate;
    
    $template = '/users/{userId}/posts/{postId}';
    $uri = UriTemplate::expand($template, [
        'userId' => 123,
        'postId' => 456
    ]);
    // Output: "/users/123/posts/456"
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

  1. Dynamic API Endpoints:

    $template = 'https://api.example.com/v1/{resource}/{id}?filter={query}';
    $uri = UriTemplate::expand($template, [
        'resource' => 'users',
        'id' => $userId,
        'query' => 'active=true'
    ]);
    
  2. Query String Expansion: Use expandQuery() for query parameters with operators:

    $template = '?{+sort},{+page}';
    $query = UriTemplate::expandQuery($template, [
        'sort' => 'name',
        'page' => 2
    ]);
    // Output: "?+sort=name&+page=2"
    
  3. Laravel HTTP Client Integration: Combine with Guzzle’s Client for API calls:

    use Illuminate\Support\Facades\Http;
    
    $uri = UriTemplate::expand('/users/{id}', ['id' => $userId]);
    $response = Http::get($uri)->json();
    
  4. Route Generation: Use in Laravel’s Route::get() with dynamic segments:

    Route::get('/{user}/posts/{post}', function ($user, $post) {
        $uri = UriTemplate::expand('/users/{user}/posts/{post}', [
            'user' => $user,
            'post' => $post
        ]);
        // Use $uri for redirects or logging
    });
    

Integration Tips

  • Validation: Sanitize variables before expansion to avoid injection (e.g., {userId} with ../).
  • Caching: Cache expanded URIs for static templates (e.g., API base URLs).
  • Error Handling: Wrap expansion in try-catch for malformed templates:
    try {
        $uri = UriTemplate::expand($template, $data);
    } catch (\InvalidArgumentException $e) {
        Log::error("URI template error: " . $e->getMessage());
    }
    
  • Query Operators: Use operators (+, &, |) for query strings to control behavior (e.g., ?{+page} adds & if present).

Gotchas and Tips

Pitfalls

  1. Empty String Expansion:

    • Issue: Variables expanding to empty strings may omit operators (e.g., ?{+var} with var = "" becomes ? instead of ?+var=).
    • Fix: Test with empty strings and adjust templates if operator preservation is critical.
    • Example:
      $template = '?{+filter}';
      $query = UriTemplate::expandQuery($template, ['filter' => '']);
      // Output: "?+filter=" (v1.0.7+ preserves `+`; older versions may drop it)
      
  2. Non-Finite Floats (PHP 8.5+):

    • Issue: INF, NAN, or 0.0 may trigger warnings in PHP 8.5.
    • Fix: Suppress warnings with @ or handle in code:
      $data = ['limit' => INF];
      $uri = @UriTemplate::expand('?{limit}', $data); // Suppress warning
      // OR validate before expansion:
      if (is_finite($data['limit'])) {
          $uri = UriTemplate::expand('?{limit}', $data);
      }
      
  3. Double Encoding:

    • Issue: Nested arrays or complex query strings may double-encode values.
    • Fix: Use expandQuery() for arrays or manually encode:
      $query = UriTemplate::expandQuery('?{filters}', [
          'filters' => ['status' => 'active', 'page' => 1]
      ]);
      // Output: "?filters[status]=active&filters[page]=1"
      
  4. Reserved Characters:

    • Issue: Values with #, ?, or & may break parsing.
    • Fix: Pre-encode or use rawurlencode:
      $data = ['query' => 'foo&bar'];
      $uri = UriTemplate::expand('?{query}', [
          'query' => rawurlencode($data['query'])
      ]);
      

Debugging Tips

  • Log Expanded URIs: Add debug logs to verify output:
    Log::debug('Expanded URI:', ['uri' => $uri]);
    
  • Test Edge Cases: Validate with:
    • Empty strings ('').
    • Non-finite floats (INF, NAN).
    • Special characters (#, ?, &).
    • Nested arrays (for query strings).
  • Compare Versions: If upgrading, test with v1.0.6 vs. v1.0.7 to catch operator/float changes.

Extension Points

  1. Custom Encoding: Override default encoding by extending UriTemplate:

    class CustomUriTemplate extends \GuzzleHttp\UriTemplate {
        protected function encodeValue($value) {
            return strtoupper($value); // Example: force uppercase
        }
    }
    
  2. Query String Parsing: Use parseQuery() to reverse-expand URIs (e.g., for logging):

    $query = UriTemplate::parseQuery('?sort=name&page=2');
    // Output: ['sort' => 'name', 'page' => '2']
    
  3. Laravel Service Provider: Bind the template as a singleton for global use:

    // app/Providers/AppServiceProvider.php
    public function register() {
        $this->app->singleton(UriTemplate::class, function () {
            return new \GuzzleHttp\UriTemplate();
        });
    }
    

    Then inject via constructor or app() helper.

Config Quirks

  • No Configuration: The package is stateless; no config/uri-template.php exists.
  • PHP Version: Ensure compatibility with your PHP version (e.g., ^1.0 for PHP 8.1+).
  • Strict Types: Enable strict_types=1 in composer.json to match the package’s defaults.
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle