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

Json Pointer Laravel Package

ergebnis/json-pointer

RFC 6901 JSON Pointer abstraction for PHP. Create and convert reference tokens and pointers between plain strings, JSON strings, and URI fragment identifiers, handling proper escaping/encoding. Install via Composer: ergebnis/json-pointer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ergebnis/json-pointer
    

    Add to composer.json under require if using Laravel's autoloader.

  2. First Use Case: Navigate to vendor/ergebnis/json-pointer to inspect the package structure. For quick testing, use the JsonPointer class in a Laravel Tinker session:

    use Ergebnis\Json\Pointer;
    
    $pointer = Pointer\JsonPointer::fromJsonString('/user/address');
    echo $pointer->toString(); // '/user/address'
    
  3. Key Classes:

    • JsonPointer: Core class for working with JSON pointers (RFC 6901).
    • ReferenceToken: Represents individual tokens in a pointer (e.g., /user/addressuser, address).
    • Specification: For validating pointers against custom rules.

Implementation Patterns

Common Workflows

1. Pointer Creation

  • From JSON String (most common in Laravel):
    $pointer = Pointer\JsonPointer::fromJsonString('/api/v1/users/123');
    
  • From URI Fragment (e.g., #/api/v1/users/123):
    $pointer = Pointer\JsonPointer::fromUriFragmentIdentifierString('#/api/v1/users/123');
    
  • From ReferenceTokens (for dynamic construction):
    $tokens = [
        Pointer\ReferenceToken::fromString('api'),
        Pointer\ReferenceToken::fromString('v1'),
        Pointer\ReferenceToken::fromString('users'),
        Pointer\ReferenceToken::fromInt(123),
    ];
    $pointer = Pointer\JsonPointer::fromReferenceTokens(...$tokens);
    

2. Pointer Manipulation

  • Appending Tokens:
    $basePointer = Pointer\JsonPointer::fromJsonString('/user');
    $newToken = Pointer\ReferenceToken::fromString('profile');
    $extendedPointer = $basePointer->append($newToken);
    // Result: '/user/profile'
    
  • Token Extraction:
    $pointer = Pointer\JsonPointer::fromJsonString('/user/123/settings');
    $tokens = $pointer->getReferenceTokens();
    // Returns array of ReferenceToken objects.
    

3. Pointer Validation (Specifications)

  • Check if Pointer Matches a Pattern:
    $spec = Pointer\Specification::closure(fn($p) => str_starts_with($p->toJsonString(), '/api'));
    $spec->isSatisfiedBy($pointer); // true if pointer starts with '/api'
    
  • Exact Match:
    $spec = Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString('/api/v1/users'));
    $spec->isSatisfiedBy($pointer); // true if exact match
    
  • Combine Specifications:
    $spec = Pointer\Specification::anyOf(
        Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString('/api/v1/users')),
        Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString('/api/v1/products'))
    );
    

4. Integration with Laravel

  • API Requests: Use JsonPointer to parse query parameters or route segments:
    $path = request()->input('path', '/default');
    $pointer = Pointer\JsonPointer::fromJsonString($path);
    
  • Eloquent Relationships: Dynamically build relationships using pointers:
    $userPointer = Pointer\JsonPointer::fromJsonString('/users/123');
    $tokens = $userPointer->getReferenceTokens();
    $userId = (int) $tokens->last()->toString();
    $user = User::find($userId);
    
  • JSON API Responses: Serialize pointers for API responses:
    return response()->json([
        'pointer' => $pointer->toJsonString(),
    ]);
    

5. Error Handling

  • Invalid Pointers:
    try {
        $pointer = Pointer\JsonPointer::fromJsonString('/invalid~pointer');
    } catch (Pointer\Exception\InvalidJsonPointer $e) {
        report($e); // Log in Laravel
        abort(400, 'Invalid JSON pointer');
    }
    

Gotchas and Tips

Pitfalls

  1. URI Fragment vs. JSON String:

    • URI fragments (e.g., #/user~1name) must be URL-encoded. Use toUriFragmentIdentifierString() for safe encoding:
      $pointer = Pointer\JsonPointer::fromJsonString('/user~1name');
      $uriFragment = $pointer->toUriFragmentIdentifierString(); // '#/user%7E1name'
      
    • Reverse with fromUriFragmentIdentifierString().
  2. Token Escaping:

    • Special characters (~, /) in tokens must be escaped in JSON strings:
      $token = Pointer\ReferenceToken::fromString('name~value');
      $jsonString = $token->toJsonString(); // 'name~0value'
      
    • Use fromJsonString() to parse escaped tokens.
  3. Empty Pointers:

    • JsonPointer::document() returns an empty pointer (''), which refers to the root of a JSON document. Ensure you handle this case when validating or traversing:
      $rootPointer = Pointer\JsonPointer::document();
      $rootPointer->toJsonString(); // ''
      
  4. Specification Logic:

    • Specification::anyOf() short-circuits (stops at the first true match). For exhaustive checks, chain specifications or use Specification::closure() with custom logic.
  5. Performance:

    • Avoid creating new Specification objects in hot loops. Reuse them:
      $spec = Pointer\Specification::equals($expectedPointer);
      foreach ($pointers as $pointer) {
          if ($spec->isSatisfiedBy($pointer)) {
              // ...
          }
      }
      

Debugging Tips

  1. Inspect Tokens: Use getReferenceTokens() to debug pointer structure:

    $tokens = $pointer->getReferenceTokens();
    foreach ($tokens as $token) {
        echo $token->toString(), "\n";
    }
    
  2. Validate Input: Sanitize user-provided pointers before processing:

    $input = request()->input('pointer');
    if (!Pointer\JsonPointer::isValidJsonPointer($input)) {
        abort(400, 'Invalid pointer format');
    }
    
  3. Laravel Logging: Log pointer operations for debugging:

    \Log::debug('Pointer created', ['pointer' => $pointer->toJsonString()]);
    

Extension Points

  1. Custom Specifications: Extend Specification for domain-specific rules:

    class ApiVersionSpecification implements Pointer\Specification
    {
        public function isSatisfiedBy(Pointer\JsonPointer $pointer): bool
        {
            $tokens = $pointer->getReferenceTokens();
            return $tokens->count() >= 2 &&
                   $tokens->first()->toString() === 'api' &&
                   $tokens->get(1)->toString() === 'v1';
        }
    }
    
  2. Pointer Builders: Create a fluent builder for complex pointers:

    class PointerBuilder
    {
        public static function build(string $path): Pointer\JsonPointer
        {
            $tokens = explode('/', trim($path, '/'));
            return Pointer\JsonPointer::fromReferenceTokens(
                ...array_map(fn($token) => Pointer\ReferenceToken::fromString($token), $tokens)
            );
        }
    }
    
  3. Laravel Service Provider: Bind the package to Laravel's container for dependency injection:

    // config/app.php
    'aliases' => [
        'JsonPointer' => Ergebnis\Json\Pointer\JsonPointer::class,
    ];
    

    Then inject JsonPointer into controllers/services:

    public function __construct(private JsonPointer $pointer) {}
    
  4. Testing: Use Specification for testing pointer logic:

    public function test_pointer_validation()
    {
        $spec = Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString('/valid/path'));
        $this->assertTrue($spec->isSatisfiedBy($pointer));
    }
    

Laravel-Specific Quirks

  1. Route Model Binding: Bind pointers to route parameters:

    Route::get('/user/{pointer}', function (Pointer\JsonPointer $pointer) {
        // $pointer is automatically validated and parsed
    });
    

    Requires a custom RouteParameterBinding implementation.

  2. Caching: Cache parsed pointers if used frequently:

    $cacheKey = 'pointer_' . md5($jsonString);
    $pointer = Cache::remember($cacheKey, now()->addHours(1), fn()
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi