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

egeloen/json-builder

PHP 5.6+ library to build JSON using Symfony PropertyAccess paths. Set nested values, arrays, and raw/unescaped values while retaining control over escaping. Produces JSON strings from a fluent builder API with strong test coverage.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Use Case Alignment: The package excels in scenarios requiring fine-grained control over JSON escaping (e.g., embedding raw JSON strings, custom serialization logic, or bypassing PHP’s default json_encode behavior). It is particularly valuable for:
    • APIs generating dynamic JSON responses with mixed data types (e.g., JSON strings, objects, or unescaped values).
    • Systems where security-sensitive data (e.g., user input) must be manually escaped to prevent injection or malformed output.
    • Laravel applications leveraging API resources, form requests, or dynamic payloads (e.g., GraphQL, WebSocket messages).
  • Symfony PropertyAccess Integration: The underlying use of Symfony’s PropertyAccess component ensures type-safe path manipulation (e.g., nested arrays/objects), reducing boilerplate for complex JSON structures.
  • Laravel Synergy:
    • Complements Laravel’s built-in json_encode() but adds escaping granularity (e.g., embedding JSON strings without double-escaping).
    • Useful for custom JSON serializers (e.g., in App\Services\JsonBuilder or API response modifiers).
    • Can integrate with Laravel’s service container for dependency injection.

Integration Feasibility

  • Low Friction: Minimal setup (Composer install + PSR-4 autoloading). No Laravel-specific dependencies, but works seamlessly with its ecosystem.
  • API Design:
    • Fluent interface (setValues()/setValue() chaining) aligns with Laravel’s method chaining patterns (e.g., Eloquent queries).
    • Immutable by default (stateful but resettable), which fits Laravel’s request/response lifecycle.
  • PHP Version Support: PHP 5.6+ (Laravel’s minimum is 8.0+, so no conflicts).

Technical Risk

  • Escaping Complexity:
    • Risk: Manual escaping control can introduce security vulnerabilities (e.g., XSS if user input is embedded without validation) or malformed JSON if misconfigured.
    • Mitigation:
      • Enforce strict validation of unescaped values (e.g., whitelist allowed types).
      • Use Laravel’s built-in sanitization (e.g., Str::of($value)->escape()) for user-provided data.
      • Document escaping rules in API contracts (e.g., OpenAPI specs).
  • Performance Overhead:
    • Risk: PropertyAccess reflection may add minor overhead for large JSON structures.
    • Mitigation: Benchmark against native json_encode() for critical paths (e.g., bulk API responses).
  • Dependency Bloat:
    • Risk: Adds Symfony’s PropertyAccess (~1MB) to the vendor tree.
    • Mitigation: Justify use case (e.g., complex nested JSON) and monitor bundle size.

Key Questions

  1. Where will this replace existing logic?
    • Current JSON generation in Laravel (e.g., response()->json(), JsonResponse) uses json_encode() with default options. Identify pain points (e.g., embedding JSON strings, custom serialization).
  2. How will escaping be governed?
    • Define rules for unescaped values (e.g., only allow strings/arrays, reject objects).
    • Example: setValue('[path]', $userInput, false)Only if $userInput is pre-sanitized.
  3. Integration with Laravel’s JSON Layer:
    • Can it extend Illuminate\Http\JsonResponse or Symfony\Component\HttpFoundation\JsonResponse?
    • Example:
      return new JsonResponse($builder->build(), 200, [], JSON_FORCE_OBJECT);
      
  4. Testing Strategy:
    • Write property-based tests for escaping edge cases (e.g., "\", \n, Unicode).
    • Validate integration with Laravel’s API testing tools (e.g., Http::fake()).
  5. Long-Term Maintenance:
    • Will Laravel’s evolving JSON features (e.g., JsonSerializable) reduce reliance on this package?
    • Monitor for upstream Symfony PropertyAccess changes.

Integration Approach

Stack Fit

  • Laravel Ecosystem:
    • API Layer: Ideal for custom JSON responses (e.g., GraphQL, WebSocket payloads, or third-party integrations).
    • Form Requests: Useful for structured error responses with mixed data (e.g., ['errors' => ['field' => 'message']]).
    • Service Layer: Replace manual json_encode() in services (e.g., App\Services\NotificationService).
    • Testing: Simplify mocking JSON responses in unit tests.
  • Alternatives Considered:
    • Laravel’s json_encode(): Lacks escaping control.
    • JsonSerializable: Requires implementing interfaces; less flexible for dynamic structures.
    • spatie/array-to-xml: Overkill for JSON.
    • nategood/prettify-json: Focuses on formatting, not escaping.

Migration Path

  1. Pilot Phase:
    • Scope: Start with one high-impact endpoint (e.g., a complex API response or WebSocket handler).
    • Example: Replace return response()->json($data) with:
      $builder = app(JsonBuilder::class);
      return response()->json($builder->setValues($data)->build());
      
  2. Incremental Adoption:
    • Step 1: Use setValues() for structured data (e.g., Eloquent collections).
    • Step 2: Introduce setValue() with false for unescaped values (e.g., embedding JSON strings).
    • Step 3: Replace custom json_encode() logic in services.
  3. Backward Compatibility:
    • Wrapper Class: Create a Laravel-specific facade (e.g., Json::builder()) to abstract the package.
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->singleton('json.builder', function () {
              return new JsonBuilder();
          });
      }
      
    • Configurable Defaults: Set default json_encode options in config/json.php:
      'default_options' => JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT,
      

Compatibility

  • Laravel Versions: Tested on PHP 8.0+ (Laravel 9/10). No breaking changes expected.
  • Package Dependencies:
    • Symfony PropertyAccess: Version v5.4+ (compatible with Laravel’s Symfony components).
    • PHP Extensions: None beyond Laravel’s requirements.
  • Edge Cases:
    • Circular References: PropertyAccess handles them, but document limitations (e.g., "avoid circular structures").
    • Non-Scalar Values: Explicitly support DateTime, Carbon, or custom objects via __toString().

Sequencing

  1. Phase 1: Core Integration (2–4 weeks)
    • Add package via Composer.
    • Create a base service (app/Services/JsonBuilderService) to wrap the package.
    • Replace 3–5 critical JSON endpoints.
  2. Phase 2: Validation (1–2 weeks)
    • Test escaping edge cases (e.g., "\", \u0000).
    • Benchmark performance vs. native json_encode().
  3. Phase 3: Expansion (Ongoing)
    • Integrate with Laravel’s HTTP layer (e.g., middleware for JSON responses).
    • Extend to queued jobs or event payloads.
  4. Phase 4: Documentation
    • Add Laravel-specific examples to the package’s README.
    • Publish a blog post on use cases (e.g., "Building Dynamic JSON in Laravel APIs").

Operational Impact

Maintenance

  • Pros:
    • MIT License: No legal risks.
    • Active Development: Regular CI (Travis/AppVeyor), 100% test coverage.
    • Laravel Alignment: Minimal drift from Symfony’s PropertyAccess (used in Laravel’s core).
  • Cons:
    • Manual Escaping: Requires developer discipline to avoid security issues.
    • Dependency Updates: Monitor Symfony PropertyAccess for breaking changes.
  • Mitigation:
    • Semantic Versioning: Pin to a minor version (e.g., ^1.2.0) in composer.json.
    • Upgrade Scripts: Automate dependency updates via composer why-not and composer why.

Support

  • Debugging:
    • Tooling: Use XDebug to inspect PropertyAccess paths (e.g., [user][0][address]).
    • Logging: Log unescaped values in development:
      if (!$escape) {
          Log::debug("Unescaped value at {$path}:", [$value]);
      }
      
  • **Common
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