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.
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