Weave 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

Basic Api Bundle Laravel Package

condenast-ru/basic-api-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use Case

  1. Installation

    composer require condenast-ru/basic-api-bundle
    

    Enable the bundle in config/bundles.php:

    Condenast\BasicApiBundle\CondenastBasicApiBundle::class => ['all' => true],
    
  2. Define a DTO Create a class annotated with #[ApiResource] and #[ApiProperty] for fields:

    use Condenast\BasicApiBundle\Annotation\ApiProperty;
    use Condenast\BasicApiBundle\Annotation\ApiResource;
    
    #[ApiResource]
    class CreateUserDto
    {
        #[ApiProperty]
        public string $name;
    
        #[ApiProperty]
        public string $email;
    }
    
  3. Annotate a Controller Use #[ApiAction] to define request/response DTOs:

    use Condenast\BasicApiBundle\Annotation\ApiAction;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class UserController
    {
        #[ApiAction(
            input: CreateUserDto::class,
            output: UserDto::class
        )]
        public function create(Request $request): Response
        {
            $dto = $request->attributes->get('input');
            // Business logic here
            return new Response(json_encode($dto));
        }
    }
    
  4. Test the Endpoint Send a POST request with JSON body:

    { "name": "John Doe", "email": "[email protected]" }
    

    The bundle auto-deserializes, validates, and serializes responses.


Implementation Patterns

Core Workflows

1. Request Handling (Deserialization + Validation)

  • DTO Binding: Annotate controller methods with #[ApiAction(input: YourDto::class)] to auto-bind request payloads.
  • Validation: Use Symfony Validator constraints (e.g., @Assert\NotBlank) alongside #[ApiProperty] for field-level validation.
    #[ApiProperty]
    #[Assert\Email]
    public string $email;
    
  • Query Parameters: Extract typed query params with #[ApiAction(query: YourQueryDto::class)].

2. Response Serialization

  • Auto-Serialization: Return DTOs or arrays of DTOs; the bundle serializes them to JSON.
  • Custom Serialization: Override JsonSerializable in DTOs for complex logic:
    class UserDto implements JsonSerializable
    {
        public function jsonSerialize(): array
        {
            return ['id' => $this->id, 'name' => $this->name];
        }
    }
    

3. Error Handling

  • Exception Serialization: The bundle converts exceptions to JSON with #[ApiError] annotations:
    #[ApiError(status: 400, message: "Invalid input")]
    class ValidationException extends \RuntimeException {}
    
  • Global Errors: Use #[ApiAction(error: YourErrorDto::class)] to customize error responses.

4. API Documentation

  • Nelmio Integration: Annotations (#[ApiResource], #[ApiProperty]) auto-generate OpenAPI docs.
  • Customize Docs: Extend NelmioApiDocBundle configuration in config/packages/nelmio_api_doc.yaml:
    nelmio_api_doc:
        documentation:
            info:
                title: My API
                description: Powered by BasicApiBundle
    

Integration Tips

Symfony Events

  • Pre/Post Processing: Listen to kernel.request or kernel.exception to modify DTOs or responses:
    use Symfony\Component\HttpKernel\Event\ExceptionEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    $eventDispatcher->addListener(KernelEvents::EXCEPTION, function (ExceptionEvent $event) {
        $exception = $event->getThrowable();
        if ($exception instanceof ValidationException) {
            $event->setResponse(new Response(json_encode(['error' => $exception->getMessage()])));
        }
    });
    

Custom Validators

  • Reusable Validation: Create custom constraints and apply them to #[ApiProperty]:
    #[Assert\CustomConstraint(MyConstraint::class)]
    #[ApiProperty]
    public string $customField;
    

Testing

  • Mock Requests: Use BasicApiBundle's test utilities:
    use Condenast\BasicApiBundle\Test\ApiTestTrait;
    
    class UserControllerTest extends WebTestCase
    {
        use ApiTestTrait;
    
        public function testCreateUser()
        {
            $client = static::createClient();
            $client->request('POST', '/users', [
                'json' => ['name' => 'Test', 'email' => '[email protected]']
            ]);
            $this->assertResponseIsSuccessful();
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Annotation Caching

    • Issue: Annotations may not update immediately after changes.
    • Fix: Clear cache:
      php bin/console cache:clear
      
    • Tip: Use #[ApiResource(cache: false)] to disable caching for specific resources.
  2. Circular References

    • Issue: DTOs with circular references (e.g., User ↔ Profile) may cause serialization errors.
    • Fix: Implement JsonSerializable or use #[ApiProperty(ignore: true)] for problematic fields.
  3. Query Parameter Conflicts

    • Issue: Query params with the same name as route params may override each other.
    • Fix: Use #[ApiAction(query: YourDto::class, queryParamPrefix: "filter_")] to namespace params.
  4. Nelmio Doc Mismatches

    • Issue: Docs may not reflect runtime behavior if annotations are incomplete.
    • Fix: Manually extend doc blocks in #[ApiResource]:
      #[ApiResource(
          description: "Creates a user with validation",
          examples: {"name": "John", "email": "[email protected]"}
      )]
      

Debugging Tips

  • Enable Debug Mode: Set APP_DEBUG=true in .env to see detailed validation errors.
  • Log DTOs: Dump request attributes in controllers:
    dump($request->attributes->get('input')); // Debug deserialized DTO
    
  • Validator Groups: Use #[ApiAction(validationGroups: {"create", "update"})] to apply group-specific validation.

Extension Points

  1. Custom Serializers

    • Extend Condenast\BasicApiBundle\Serializer\Serializer to add custom normalization:
    class CustomSerializer extends Serializer
    {
        public function normalize($object, $format, array $context = [])
        {
            if ($object instanceof YourDto) {
                return ['custom' => 'value'];
            }
            return parent::normalize($object, $format, $context);
        }
    }
    

    Register as a service with tags: ["basic_api.serializer"].

  2. Dynamic DTOs

    • Use #[ApiProperty(type: "array")] for dynamic arrays or #[ApiProperty(type: "object")] for JSON blobs.
  3. Middleware Integration

    • Add pre-processing logic via Symfony middleware:
    class ApiMiddleware implements MiddlewareInterface
    {
        public function handle(Request $request, callable $next): Response
        {
            $request->attributes->set('custom_header', $request->headers->get('X-Custom'));
            return $next($request);
        }
    }
    

Configuration Quirks

  • Default Validation Groups: Override in config/packages/validator.yaml:
    validator:
        default_groups: [default, "basic_api"]
    
  • Serializer Context: Pass custom context to serializers via #[ApiAction(serializerContext: {"groups": "api"})].

Performance

  • Batch Processing: For large arrays, use #[ApiProperty(type: "array", itemType: YourDto::class)] with validation_groups to optimize validation.
  • Avoid Redundant Validation: Disable validation for read-only endpoints:
    #[ApiAction(validation: false)]
    
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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin