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

Jv Rest Bundle Laravel Package

asjustas/jv-rest-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require asjustas/jv-rest-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Justas\RestBundle\JustasRestBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Create a DTO (Data Transfer Object) for request validation. Example:

    // src/Dto/UserCreateDto.php
    namespace App\Dto;
    
    use Justas\RestBundle\Validator\Constraints as RestAssert;
    
    class UserCreateDto
    {
        /**
         * @RestAssert\NotBlank()
         * @RestAssert\Length(max=255)
         */
        public string $name;
    
        /**
         * @RestAssert\Email()
         */
        public string $email;
    }
    
  3. Configure Controller: Use the RestController trait to auto-validate and serialize requests:

    // src/Controller/UserController.php
    namespace App\Controller;
    
    use App\Dto\UserCreateDto;
    use Justas\RestBundle\Controller\RestController;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class UserController extends RestController
    {
        public function create(Request $request, UserCreateDto $dto): Response
        {
            // $dto is automatically validated and populated
            return $this->json(['success' => true]);
        }
    }
    
  4. Routing:

    # config/routes.yaml
    user_create:
        path: /users
        controller: App\Controller\UserController::create
        methods: POST
    

Implementation Patterns

Workflows

  1. Request Validation:

    • Use DTOs annotated with @RestAssert constraints (e.g., @RestAssert\NotBlank(), @RestAssert\Length()).
    • The bundle automatically validates requests against these constraints and returns standardized error responses.
  2. Response Serialization:

    • Leverage JMS Serializer (included via jms/serializer-bundle) to serialize responses.
    • Annotate entities/DTOs with @Serializer\SerializedName or @Serializer\Type for custom serialization logic.
  3. Exception Handling:

    • Extend Justas\RestBundle\Exception\RestException for custom error responses.
    • Example:
      class ValidationException extends RestException
      {
          public function __construct(array $errors)
          {
              parent::__construct('Validation failed', Response::HTTP_BAD_REQUEST, ['errors' => $errors]);
          }
      }
      
  4. Event-Driven Extensions:

    • Dispatch events (e.g., RestRequestEvent, RestResponseEvent) to modify requests/responses globally.
    • Example listener:
      // src/EventListener/AddTimestampListener.php
      namespace App\EventListener;
      
      use Justas\RestBundle\Event\RestRequestEvent;
      use Symfony\Component\EventDispatcher\EventSubscriberInterface;
      
      class AddTimestampListener implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  RestRequestEvent::class => 'onRestRequest',
              ];
          }
      
          public function onRestRequest(RestRequestEvent $event)
          {
              $event->getRequest()->query->set('timestamp', time());
          }
      }
      
  5. Field Inclusion Rules:

    • Use JMS Serializer’s @Groups annotation to control which fields are serialized.
    • Example:
      use JMS\Serializer\Annotation as Serializer;
      
      class UserDto
      {
          /**
           * @Serializer\Groups({"public"})
           */
          public string $name;
      
          /**
           * @Serializer\Groups({"admin"})
           */
          public string $email;
      }
      

Integration Tips

  1. Symfony Flex Compatibility:

    • Ensure jms/serializer-bundle is installed and configured (run composer require jms/serializer-bundle if missing).
  2. Doctrine Annotations:

    • The bundle relies on Doctrine Annotations for validation. Ensure doctrine/annotations is installed and autoloaded.
  3. Custom Constraints:

    • Create custom validation constraints by extending Symfony\Component\Validator\Constraint and register them as services.
  4. Testing:

    • Use PHPUnit to test DTO validation and serialization. Example:
      public function testUserCreateDtoValidation()
      {
          $dto = new UserCreateDto();
          $dto->name = '';
          $dto->email = 'invalid-email';
      
          $validator = $this->getValidator();
          $errors = $validator->validate($dto);
      
          $this->assertCount(2, $errors);
      }
      

Gotchas and Tips

Pitfalls

  1. Validation Errors:

    • By default, validation errors are returned as a JSON array under the errors key. Customize this behavior by overriding the RestException or creating a custom error formatter.
  2. Circular References:

    • JMS Serializer may fail on circular references (e.g., UserProfile). Use @Serializer\MaxDepth or @Serializer\ExclusionPolicy to handle this.
  3. Annotation Parsing:

    • Ensure Doctrine Annotations are properly autoloaded. If validation constraints are ignored, check your autoload-dev.php or composer.json for annotation loading.
  4. Event Dispatcher Order:

    • Events like RestRequestEvent are dispatched early in the request lifecycle. Be mindful of dependencies (e.g., services not yet initialized).
  5. Symfony Version Mismatches:

    • The bundle supports Symfony 4.4 and 5.0. Ensure your composer.json constraints align with the bundle’s requirements to avoid autowiring issues.

Debugging Tips

  1. Enable Debug Mode:

    • Symfony’s debug toolbar can help inspect validation errors, request/response cycles, and event listeners.
  2. Log Validation Errors:

    • Add a listener to log validation errors for debugging:
      use Justas\RestBundle\Event\RestExceptionEvent;
      use Psr\Log\LoggerInterface;
      
      class ValidationErrorLogger implements EventSubscriberInterface
      {
          private LoggerInterface $logger;
      
          public function __construct(LoggerInterface $logger)
          {
              $this->logger = $logger;
          }
      
          public static function getSubscribedEvents()
          {
              return [
                  RestExceptionEvent::class => 'onRestException',
              ];
          }
      
          public function onRestException(RestExceptionEvent $event)
          {
              $this->logger->error('Validation Error', ['errors' => $event->getException()->getErrors()]);
          }
      }
      
  3. Check Event Subscribers:

    • Use debug:event-dispatcher to list all subscribed events and their order:
      php bin/console debug:event-dispatcher
      
  4. Serializer Configuration:

    • If serialization fails, dump the configuration:
      $serializer = $this->container->get('jms_serializer');
      dump($serializer->getConfiguration());
      

Extension Points

  1. Custom Validation Constraints:

    • Create reusable constraints by extending Symfony\Component\Validator\Constraint and ConstraintValidator. Register them as services:
      # config/services.yaml
      App\Validator\Constraints\CustomConstraintValidator:
          tags: { name: validator.constraint_validator }
      
  2. Dynamic DTOs:

    • Use Justas\RestBundle\Validator\DynamicDtoValidator to validate dynamic data (e.g., from nested JSON payloads).
  3. Response Transformers:

    • Extend Justas\RestBundle\Serializer\ResponseTransformer to modify serialized responses globally.
  4. Security Integration:

    • Combine with Symfony’s security component to validate authenticated user roles in DTOs:
      use Justas\RestBundle\Validator\Constraints as RestAssert;
      use Symfony\Component\Security\Core\AuthenticationTokenStorageInterface;
      
      class AdminUserDto
      {
          /**
           * @RestAssert\Role("ROLE_ADMIN")
           */
          public function isAdmin(AuthenticationTokenStorageInterface $storage)
          {
              return $storage->getToken()->getUser()->hasRole('ROLE_ADMIN');
          }
      }
      
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