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

Restful Bundle Laravel Package

antonchernik/restful-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require antonchernik/restful-bundle
    

    Add to config/bundles.php:

    RestfulBundle\RestfulBundle::class => ['all' => true],
    
  2. Basic Configuration In config/services.yaml:

    parameters:
      restful_bundle.validation.message_map: !php/const App\Dictionary\ValidationMessages::MESSAGE_MAP
    

    (Use RestfulBundle\Dictionary\ValidationMessages::MESSAGE_MAP if no custom messages.)

  3. First Use Case Create a DTO (via antonchernik/dto-bundle) and annotate it with @Restful\ApiResource:

    use RestfulBundle\Annotation\ApiResource;
    
    #[ApiResource(
        collectionOperations: ['get', 'post'],
        itemOperations: ['get', 'put', 'delete']
    )]
    class UserDto {}
    

    Register the DTO in your controller:

    use RestfulBundle\Controller\AbstractRestfulController;
    
    class UserController extends AbstractRestfulController
    {
        public function __construct(private UserDto $dto) {}
    }
    

Implementation Patterns

1. DTO-Driven API Development

  • Pattern: Use DTOs for all API input/output. The bundle auto-maps request data to DTOs and validates them.
    #[ApiResource(
        collectionOperations: ['get', 'post' => ['method' => 'POST', 'validation_groups' => ['create']]],
        itemOperations: ['get', 'put' => ['validation_groups' => ['update']]]
    )]
    class PostDto {}
    
    • Validation: Leverage Symfony’s validator with custom message_map for localized errors.
    • Serialization: Auto-serializes DTOs to JSON using justinrainbow/json-schema.

2. Controller Abstraction

  • Extend AbstractRestfulController to inherit CRUD logic:
    class ProductController extends AbstractRestfulController
    {
        public function __construct(private ProductDto $dto) {}
    
        // Override methods for custom logic (e.g., `createItemAction`).
    }
    
    • Key Methods:
      • collection(): Handles GET /collection, POST /collection.
      • item(): Handles GET /item, PUT/PATCH /item, DELETE /item.

3. Custom Operations

  • Add non-standard operations (e.g., publish):
    #[ApiResource(
        itemOperations: [
            'publish' => [
                'method' => 'POST',
                'path' => '/{id}/publish',
                'controller' => [UserController::class, 'publishAction']
            ]
        ]
    )]
    class UserDto {}
    
    • Implement the action in your controller:
      public function publishAction(UserDto $dto): Response
      {
          // Custom logic...
          return $this->json($dto);
      }
      

4. Request/Response Transformation

  • Use RestfulBundle\Transformer\DtoTransformer to customize serialization:
    $transformer = new DtoTransformer($dto);
    $data = $transformer->transform(['include' => ['author']]);
    
    • Nested Includes: Support for nested DTO relationships (e.g., include=author,comments).

5. Logging and Monitoring

  • Integrate with antonchernik/logging-bundle for API request logging:
    $this->logger->info('API Request', [
        'dto' => $dto,
        'method' => $request->getMethod(),
        'path' => $request->getPathInfo()
    ]);
    

Gotchas and Tips

Pitfalls

  1. DTO Validation Groups

    • Forgetting to specify validation_groups in @ApiResource causes all constraints to run on every operation.
    • Fix: Explicitly define groups per operation:
      post: ['validation_groups' => ['create']]
      put: ['validation_groups' => ['update']]
      
  2. Circular References in DTOs

    • Nested DTOs with circular references (e.g., UserPost) may cause serialization errors.
    • Fix: Use @Restful\Ignore on problematic properties or configure DtoTransformer to handle cycles.
  3. Overriding Default Paths

    • Custom paths in @ApiResource must include {id} for item operations or the bundle’s router won’t bind the DTO.
    • Fix: Use {id} in paths like /items/{id}.
  4. Symfony 6+ Sensio Extensions

    • The bundle requires sensio/framework-extra-bundle v6+. Older versions may break route binding.
    • Fix: Update to ^6.0 and clear cache:
      composer require sensio/framework-extra-bundle:^6.0
      php bin/console cache:clear
      

Debugging Tips

  1. Validation Errors

    • Check the message_map parameter in services.yaml for custom error messages.
    • Enable Symfony’s validator debug mode:
      # config/packages/validator.yaml
      validator:
          enable_annotation_reader: true
      
  2. DTO Binding Issues

    • Use dd($this->getDto()) in your controller to inspect bound data.
    • Verify DTO properties match request payload keys (case-sensitive).
  3. Serialization Quirks

    • If JSON output is malformed, check for:
      • Non-serializable properties (e.g., DateTime without a getter).
      • Custom JsonSerializable implementations conflicting with the transformer.

Extension Points

  1. Custom Transformers

    • Extend DtoTransformer to add logic:
      class CustomTransformer extends DtoTransformer
      {
          protected function transformProperty($property, $value): mixed
          {
              if ($property === 'price') {
                  return number_format($value, 2);
              }
              return parent::transformProperty($property, $value);
          }
      }
      
    • Register it in services.yaml:
      services:
          App\Transformer\CustomTransformer: ~
      
  2. Event Listeners

    • Tap into the bundle’s lifecycle with events (e.g., restful.pre_validate):
      use RestfulBundle\Event\PreValidateEvent;
      
      $eventDispatcher->addListener(PreValidateEvent::NAME, function (PreValidateEvent $event) {
          if ($event->getDto() instanceof UserDto) {
              $event->setValidationGroups(['create', 'custom']);
          }
      });
      
  3. Dynamic DTOs

    • Use antonchernik/dto-bundle’s DynamicDto for runtime-generated schemas:
      $dynamicDto = new DynamicDto([
          'name' => ['type' => 'string', 'constraints' => [new NotBlank()]],
          'tags' => ['type' => 'array', 'items' => ['type' => 'string']]
      ]);
      
  4. API Versioning

    • Combine with Symfony’s api_platform or nelmio/api-doc-bundle for versioned endpoints:
      # config/routes.yaml
      app_api_v1:
          resource: "@RestfulBundle/Resources/config/routing/v1.yaml"
          prefix: /api/v1
      
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