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, parse, and encode reference tokens from plain strings, JSON strings, or URI fragment identifiers, with helpers to output JSON-safe and URI-safe forms. 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 not using Composer directly.

  2. First Use Case: Navigate to a nested JSON value using a pointer:

    use Ergebnis\Json\Pointer;
    
    $pointer = Pointer\JsonPointer::fromJsonString('/user/profile/address');
    $data = json_decode('{"user": {"profile": {"address": "123 Main St"}}}', true);
    $address = $pointer->resolve($data); // Returns "123 Main St"
    

Where to Look First

  • Core Classes:

    • JsonPointer: Main class for constructing and manipulating pointers.
    • ReferenceToken: Represents individual segments of a pointer (e.g., user, profile).
    • Specification: For validating pointers against custom rules.
  • Key Methods:

    • fromJsonString(), fromUriFragmentIdentifierString(): Create pointers from strings.
    • toJsonString(), toUriFragmentIdentifierString(): Convert pointers to strings.
    • append(): Extend a pointer with new segments.
    • resolve(): Extract data from JSON using the pointer (not built-in; see Implementation Patterns).

Implementation Patterns

1. Pointer Construction

  • From JSON Path:
    $pointer = Pointer\JsonPointer::fromJsonString('/users/0/name');
    
  • From URI Fragment:
    $pointer = Pointer\JsonPointer::fromUriFragmentIdentifierString('#/users/0/name');
    
  • From Reference Tokens:
    $tokens = [
        Pointer\ReferenceToken::fromString('users'),
        Pointer\ReferenceToken::fromInt(0),
        Pointer\ReferenceToken::fromString('name'),
    ];
    $pointer = Pointer\JsonPointer::fromReferenceTokens(...$tokens);
    

2. Dynamic Pointers

  • Build Pointers Programmatically:
    $basePointer = Pointer\JsonPointer::fromJsonString('/users');
    $userId = 1;
    $pointer = $basePointer->append(Pointer\ReferenceToken::fromInt($userId));
    

3. Data Resolution

  • Extract Data from JSON: Use a helper function or service to resolve pointers against JSON data:
    function resolvePointer(Pointer\JsonPointer $pointer, array $data): mixed {
        $current = $data;
        foreach ($pointer->getReferenceTokens() as $token) {
            $current = $current[$token->toString()] ?? null;
            if ($current === null) break;
        }
        return $current;
    }
    
    $data = ['users' => [['name' => 'Alice']]];
    $pointer = Pointer\JsonPointer::fromJsonString('/users/0/name');
    $name = resolvePointer($pointer, $data); // 'Alice'
    

4. Validation with Specifications

  • Check Pointer Structure:
    $spec = Pointer\Specification::closure(fn($p) => str_starts_with($p->toJsonString(), '/users'));
    $spec->isSatisfiedBy($pointer); // true if pointer starts with '/users'
    
  • Combine Specifications:
    $spec = Pointer\Specification::anyOf(
        Pointer\Specification::equals($pointer1),
        Pointer\Specification::closure(fn($p) => $p->toJsonString() === '/users/1')
    );
    

5. URI/URL Integration

  • Encode Pointers for URLs:
    $uriFragment = $pointer->toUriFragmentIdentifierString(); // e.g., '#/users/0'
    $url = "https://api.example.com/data{$uriFragment}";
    

Gotchas and Tips

Pitfalls

  1. Null Resolution:

    • If a pointer segment doesn’t exist in the JSON, resolve() (custom implementation) returns null. Handle this explicitly:
      $value = resolvePointer($pointer, $data) ?? 'default';
      
  2. URI Fragment Encoding:

    • URI fragments (#/path) require percent-encoding for special characters. Use toUriFragmentIdentifierString() instead of manual encoding:
      // ❌ Avoid manual encoding (e.g., str_replace)
      // ✅ Use:
      $fragment = $pointer->toUriFragmentIdentifierString();
      
  3. Integer Tokens:

    • Integers in pointers (e.g., /users/0) are treated as strings when resolved. Ensure your JSON uses numeric indices if needed:
      $data = ['users' => [['name' => 'Alice']]]; // Correct
      $data = ['users' => [{'0': ['name' => 'Alice']}]]; // Incorrect
      
  4. Specification Logic:

    • Specification::closure() captures the closure’s scope. Avoid referencing non-serializable variables:
      // ❌ Risky (closes over $userId)
      $spec = Pointer\Specification::closure(fn($p) => $p->toJsonString() === "/users/{$userId}");
      // ✅ Safer
      $spec = Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString("/users/{$userId}"));
      

Debugging Tips

  1. Inspect Pointers:

    • Use toJsonString() or toString() to debug pointer structures:
      dump($pointer->toJsonString()); // '/users/0/name'
      
  2. Validate JSON:

    • Ensure JSON data matches the pointer’s structure. Use json_last_error() if resolution fails:
      $json = json_encode($data);
      if (json_last_error() !== JSON_ERROR_NONE) {
          throw new \RuntimeException('Invalid JSON');
      }
      
  3. Handle Edge Cases:

    • Empty pointers (JsonPointer::document()) refer to the root of the JSON object.
    • Trailing slashes (e.g., /users/) are valid but may cause issues in resolution. Trim if necessary:
      $pointerStr = trim($pointer->toJsonString(), '/');
      

Extension Points

  1. Custom Resolvers:

    • Extend the resolve() logic for complex JSON (e.g., arrays of objects):
      class CustomResolver {
          public function resolve(Pointer\JsonPointer $pointer, array $data): mixed {
              // Custom logic (e.g., handle wildcards, arrays)
          }
      }
      
  2. Pointer Builders:

    • Create a fluent interface for dynamic pointer construction:
      class PointerBuilder {
          private $tokens = [];
      
          public function segment(string $segment): self {
              $this->tokens[] = Pointer\ReferenceToken::fromString($segment);
              return $this;
          }
      
          public function build(): Pointer\JsonPointer {
              return Pointer\JsonPointer::fromReferenceTokens(...$this->tokens);
          }
      }
      
      $pointer = (new PointerBuilder())
          ->segment('users')
          ->segment('0')
          ->segment('name')
          ->build();
      
  3. Specification Extensions:

    • Add custom validation rules (e.g., regex matching):
      Pointer\Specification::closure(fn($p) => preg_match('/^\/users\/\d+$/', $p->toJsonString()));
      

Performance Notes

  • Avoid Repeated Parsing:
    • Parse JSON once and reuse the decoded array for multiple pointer resolutions.
  • Cache Pointers:
    • Reuse JsonPointer and ReferenceToken objects if the same pointer is used frequently.
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport