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

Jsonapi Bundle Laravel Package

bornfight/jsonapi-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require paknahad/jsonapi-bundle
    

    Add to config/bundles.php:

    Paknahad\JsonApiBundle\JsonApiBundle::class => ['all' => true],
    
  2. Generate a JSON:API-compliant Entity: Use Symfony MakerBundle to scaffold an entity (e.g., Book):

    bin/console make:entity Book
    

    Ensure your entity uses Doctrine ORM annotations (e.g., @ORM\Entity).

  3. First API Endpoint: Create a controller extending JsonApiController (provided by the bundle):

    use Paknahad\JsonApiBundle\Controller\JsonApiController;
    
    class BookController extends JsonApiController
    {
        public function index(): Response
        {
            return $this->jsonApiResponse($this->getDoctrine()->getRepository(Book::class)->findAll());
        }
    }
    

    Route it in config/routes.yaml:

    api_books:
        path: /api/books
        controller: App\Controller\BookController::index
        methods: GET
    
  4. Test the Endpoint: Visit /api/books to see JSON:API-formatted output (e.g., data, links, meta).


Where to Look First

  • Bundle Docs: Check the GitHub README for quick-start examples.
  • Yin Library: Understand woohoolabs/yin (the underlying library) for JSON:API serialization logic.
  • Controller Base Class: Extend JsonApiController for standardized responses.
  • Configuration: Review config/packages/jsonapi.yaml (if auto-generated) for global settings.

First Use Case

Fetch and Serialize a Resource:

// src/Controller/BookController.php
use Paknahad\JsonApiBundle\Controller\JsonApiController;

class BookController extends JsonApiController
{
    public function show(Book $book): Response
    {
        return $this->jsonApiResponse($book); // Auto-serializes to JSON:API format
    }
}

Route:

api_book_show:
    path: /api/books/{id}
    controller: App\Controller\BookController::show
    methods: GET

Output:

{
  "data": {
    "type": "books",
    "id": "1",
    "attributes": {
      "title": "Laravel JSON:API",
      "published_at": "2023-01-01"
    }
  }
}

Implementation Patterns

Core Workflows

  1. Entity Serialization:

    • Annotate entities with Doctrine ORM (e.g., @ORM\Column, @ORM\ManyToOne).
    • The bundle leverages woohoolabs/yin to auto-convert entities to JSON:API.
    • Example:
      class Book
      {
          /**
           * @ORM\ManyToOne(targetEntity="Author")
           */
          private $author;
      }
      
      Output includes nested author under relationships.
  2. Customizing Responses:

    • Override jsonApiResponse() in your controller:
      return $this->jsonApiResponse($data, 200, [
          'meta' => ['custom' => 'value'],
          'links' => ['self' => '/api/books/1']
      ]);
      
    • Use JsonApiResponse class directly for granular control.
  3. Pagination:

    • Use Paginator (Symfony) and pass to jsonApiResponse:
      $paginator = $this->getDoctrine()->getRepository(Book::class)->findAll();
      $paginator->setItemOptions(['resource' => 'books']);
      return $this->jsonApiResponse($paginator);
      
    • Output includes links for pagination (e.g., first, last, next).
  4. Relationships:

    • Define relationships via Doctrine annotations (e.g., @ORM\ManyToOne).
    • Include related data in responses:
      return $this->jsonApiResponse($book, null, [
          'include' => ['author'] // Eager-loads author data
      ]);
      

Integration Tips

  1. Symfony MakerBundle:

    • Use make:entity to scaffold JSON:API-ready entities.
    • Example command:
      bin/console make:entity Book --fields="title:string author:ManyToOne:Author"
      
  2. API Platform Integration:

    • If using API Platform, configure jsonapi-bundle as the serializer:
      # config/packages/api_platform.yaml
      api_platform:
          formats:
              jsonapi: ['application/vnd.api+json']
          serialization_groups: [jsonapi]
      
  3. Validation:

    • Use Symfony Validator for input validation:
      use Symfony\Component\Validator\Constraints as Assert;
      
      class Book
      {
          /**
           * @Assert\NotBlank
           */
          private $title;
      }
      
    • Errors are auto-included in JSON:API errors field.
  4. Testing:

    • Test JSON:API responses with PHPUnit:
      $client = static::createClient();
      $client->request('GET', '/api/books');
      $response = $client->getResponse();
      $this->assertJsonApiResponse($response, 200);
      
    • Use custom assertions (e.g., assertJsonApiAttribute()).

Advanced Patterns

  1. Dynamic Resource Types:

    • Override getResourceType() in your controller for dynamic types:
      public function getResourceType(): string
      {
          return 'dynamic_books';
      }
      
  2. Custom Serializers:

    • Extend JsonApiSerializer to handle custom logic:
      use Paknahad\JsonApiBundle\Serializer\JsonApiSerializer;
      
      class CustomSerializer extends JsonApiSerializer
      {
          protected function serializeAttribute($attribute, $value)
          {
              if ($attribute === 'title') {
                  return strtoupper($value);
              }
              return parent::serializeAttribute($attribute, $value);
          }
      }
      
    • Bind it in services.yaml:
      services:
          Paknahad\JsonApiBundle\Serializer\JsonApiSerializer:
              class: App\Serializer\CustomSerializer
      
  3. GraphQL-like Queries:

    • Use query parameters to filter/include fields:
      // GET /api/books?fields[books]=title&include=author
      
    • Configure in config/packages/jsonapi.yaml:
      jsonapi:
          fields:
              books: [title, published_at]
          include: ['author']
      

Gotchas and Tips

Pitfalls

  1. Entity Annotations:

    • Issue: Missing @ORM\Entity or incorrect annotations break serialization.
    • Fix: Ensure all entities are properly annotated. Use make:entity for consistency.
    • Tip: Run bin/console doctrine:schema:validate to catch issues early.
  2. Circular References:

    • Issue: Bidirectional relationships (e.g., Book <-> Author) can cause infinite loops.
    • Fix: Use exclude in jsonApiResponse or configure yin to ignore cycles:
      jsonapi:
          yin:
              ignore_circular_references: true
      
  3. Pagination Conflicts:

    • Issue: Custom paginators may not align with JSON:API links.
    • Fix: Use Symfony’s Paginator or KnpPaginatorBundle for compatibility.
  4. Caching Headers:

    • Issue: Missing Cache-Control headers can cause performance issues.
    • Fix: Add headers manually or configure the bundle:
      jsonapi:
          response_headers:
              Cache-Control: 'public, max-age=3600'
      

Debugging

  1. Enable Verbose Logging:

    • Add to config/packages/dev/jsonapi.yaml:
      jsonapi:
          debug: true
      
    • Check logs for serialization details in var/log/dev.log.
  2. Inspect Serialized Data:

    • Use dd() to debug the object before serialization:
      $book = $this->getDoctrine()->getRepository(Book::class)->find(1);
      dd($book); // Inspect structure
      return $this->jsonApiResponse($book);
      
  3. Validate JSON:API Output:

    • Use JSON:API Linter to validate responses.
    • Example cURL command:
      curl -H "Accept: application/vnd.api+json" http://localhost/api/books | \
      jsonapi-lint --format json
      

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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware