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

Response Content Negotiation Bundle Laravel Package

gisostallenberg/response-content-negotiation-bundle

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require gisostallenberg/response-content-negotiation-bundle
    

    Add to config/bundles.php:

    Gisostallenberg\ResponseContentNegotiationBundle\ResponseContentNegotiationBundle::class => ['all' => true],
    
  2. Basic Usage In a controller, annotate your action with #[ResponseContentNegotiation]:

    use Gisostallenberg\ResponseContentNegotiationBundle\Annotation\ResponseContentNegotiation;
    
    #[ResponseContentNegotiation]
    public function index(): array
    {
        return ['data' => 'example'];
    }
    

    The bundle will automatically negotiate responses based on Accept headers.

  3. First Use Case Return a JSON API response for Accept: application/vnd.api+json or HTML for Accept: text/html.


Implementation Patterns

Common Workflows

  1. Explicit Format Handling Use #[ResponseContentNegotiation] with formats to restrict supported formats:

    #[ResponseContentNegotiation(formats: ['json', 'html'])]
    public function show(): array
    {
        return ['id' => 1, 'name' => 'Test'];
    }
    
  2. Custom Formatters Register custom formatters in config/packages/gisostallenberg_response_content_negotiation.yaml:

    gisostallenberg_response_content_negotiation:
        formatters:
            csv:
                class: App\Formatter\CsvFormatter
                priority: 10
    
  3. Dynamic Response Logic Use #[ResponseContentNegotiation] with fallback to default to a format:

    #[ResponseContentNegotiation(fallback: 'json')]
    public function list(): array
    {
        return ['items' => []];
    }
    
  4. Integration with Symfony Serializer Leverage Symfony’s serializer for complex objects:

    use Symfony\Component\Serializer\Annotation\Groups;
    
    class User {
        #[Groups(['default'])]
        public string $name;
    }
    

Best Practices

  • Prioritize Formats: Higher priority formats (e.g., application/vnd.api+json) should be registered first.
  • Fallback Strategy: Always define a fallback to avoid 406 Not Acceptable errors.
  • Testing: Use Accept headers in tests:
    $client->request('GET', '/api/users', [], [], ['HTTP_ACCEPT' => 'application/json']);
    

Gotchas and Tips

Pitfalls

  1. Missing Accept Header Without an Accept header, the bundle defaults to text/html. Explicitly set fallback to avoid surprises:

    #[ResponseContentNegotiation(fallback: 'json')]
    
  2. Caching Headers Ensure Vary: Accept is set in responses to prevent caching issues across formats. Override the ResponseListener if needed.

  3. Annotation Overrides Controller annotations override bundle config. Test edge cases where both are defined.

  4. Priority Conflicts Formatters with the same priority may lead to inconsistent behavior. Assign unique priorities:

    formatters:
        json:
            priority: 20
        xml:
            priority: 10
    

Debugging Tips

  • Check Negotiated Format Log the resolved format in your controller:

    #[ResponseContentNegotiation]
    public function index(): array
    {
        $format = $this->get('gisostallenberg_response_content_negotiation.negotiator')->getNegotiatedFormat();
        \Log::info('Negotiated format:', ['format' => $format]);
        return ['data' => 'example'];
    }
    
  • Validate Headers Use bin/console debug:container to inspect the Negotiator service and its configuration.

Extension Points

  1. Custom Negotiator Override the default negotiator by binding your own service:

    services:
        Gisostallenberg\ResponseContentNegotiationBundle\Negotiator\NegotiatorInterface: '@app.custom_negotiator'
    
  2. Event Listeners Subscribe to response_content_negotiation.resolve events to modify negotiation logic dynamically.

  3. Format-Specific Logic Use #[ResponseContentNegotiation] with formats to restrict or extend supported formats per endpoint.

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