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

Direct Bundle Laravel Package

atoermer/direct-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require atoermer/direct-bundle
    

    Enable the bundle in config/bundles.php:

    Atoermer\DirectBundle\AtoermerDirectBundle::class => ['all' => true],
    
  2. Basic Configuration Add routing in config/routes.yaml:

    direct:
        resource: "@AtoermerDirectBundle/Resources/config/routing.yml"
        prefix: /api
    
  3. First Use Case: Exposing a Controller Action Annotate a controller method with @Direct:

    use Atoermer\DirectBundle\Annotation\Direct;
    
    class UserController extends AbstractController
    {
        /**
         * @Direct()
         */
        public function getUsers()
        {
            return $this->json(['users' => User::all()]);
        }
    }
    
  4. Client-Side Usage Configure ExtJS to point to /api/direct.php and call:

    Ext.Direct.addProvider({
        url: '/api/direct.php',
        type: 'remoting',
        actionMap: {
            'MyApp.user.getUsers': {
                formHandler: true
            }
        }
    });
    
    Ext.Direct.MyApp.user.getUsers({}, function(response) {
        console.log(response.users);
    });
    

Implementation Patterns

Controller Integration

  • Annotation-Based Routing Use @Direct on methods to expose them as ExtDirect endpoints. Supports:

    /**
     * @Direct(
     *     name="getUserById",
     *     returnType="array",
     *     params={
     *         "userId"={"type":"integer", "required":true}
     *     }
     * )
     */
    public function getUserById($userId) { ... }
    
  • Dependency Injection Inject services into annotated methods:

    public function __construct(private UserRepository $userRepo) {}
    
    /**
     * @Direct()
     */
    public function listActiveUsers() {
        return $this->json($this->userRepo->findActive());
    }
    

Request Handling

  • Param Validation Leverage Symfony’s validator for input validation:

    /**
     * @Direct(
     *     params={
     *         "data"={"type":"array", "validator":"@validator"}
     *     }
     * )
     */
    public function createUser(array $data, ValidatorInterface $validator) {
        $errors = $validator->validate($data);
        if (count($errors)) { throw new \RuntimeException('Validation failed'); }
        // ...
    }
    
  • Async Support Use Symfony’s Messenger for background processing:

    /**
     * @Direct()
     */
    public function asyncTask($payload, MessengerInterface $messenger) {
        $message = new ProcessTask($payload);
        $messenger->dispatch($message);
        return $this->json(['status' => 'queued']);
    }
    

Response Patterns

  • Standardized Responses Return consistent JSON structures:

    return $this->json([
        'success' => true,
        'data' => $user->toArray(),
        'total' => User::count()
    ]);
    
  • Error Handling Throw exceptions for ExtDirect-compatible errors:

    throw new \RuntimeException('User not found', 404, [
        'code' => 'USER_NOT_FOUND',
        'message' => 'The requested user does not exist.'
    ]);
    

Workflows

  1. CRUD Operations Expose create, read, update, delete methods with @Direct and handle ExtJS’s Ext.data.Store operations.

  2. Real-Time Updates Combine with Symfony’s Mercure or WebSocket bundles for push notifications:

    // Client-side
    Ext.Direct.on({
        scope: this,
        userUpdated: function(user) {
            this.updateView(user);
        }
    });
    
  3. Authentication Secure endpoints with Symfony’s security component:

    /**
     * @Direct(
     *     security="is_granted('ROLE_ADMIN')"
     * )
     */
    public function adminOnlyAction() { ... }
    

Gotchas and Tips

Common Pitfalls

  1. CORS Issues Ensure your server sends proper CORS headers. Configure in .env:

    SYMFONY_TRUSTED_PROXIES=127.0.0.1
    SYMFONY_TRUSTED_HOSTS=^localhost|yourdomain\.com$
    

    Add middleware in config/packages/security.yaml:

    enable_authenticator_manager: true
    stateless: true
    
  2. Annotation Processing Clear the cache after adding @Direct annotations:

    php bin/console cache:clear
    
  3. ExtJS Version Mismatch DirectBundle follows ExtDirect 1.0. Ensure your ExtJS version (e.g., ExtJS 4/5) is compatible. For ExtJS 6+, use Ext.app.Direct instead of Ext.Direct.

  4. Parameter Type Casting DirectBundle does not auto-cast parameters. Explicitly type-hint or validate:

    // Bad: Assumes $id is integer
    public function getById($id) { ... }
    
    // Good: Explicit or validated
    public function getById(int $id) { ... }
    

Debugging Tips

  • Enable Verbose Logging Add to config/packages/monolog.yaml:

    handlers:
        direct:
            type: stream
            path: "%kernel.logs_dir%/direct.log"
            level: debug
            channels: ["direct"]
    

    Log DirectBundle events in your controller:

    use Psr\Log\LoggerInterface;
    
    public function __construct(private LoggerInterface $logger) {}
    
    /**
     * @Direct()
     */
    public function debugAction() {
        $this->logger->debug('Direct call received', ['params' => func_get_args()]);
        return $this->json(['status' => 'ok']);
    }
    
  • Check DirectBundle Events Listen for direct.request and direct.response events in EventSubscriber:

    use Atoermer\DirectBundle\Event\DirectEvent;
    
    public function onDirectRequest(DirectEvent $event) {
        $request = $event->getRequest();
        $this->logger->info('Direct call', [
            'action' => $request->get('_action'),
            'params' => $request->request->all()
        ]);
    }
    

Extension Points

  1. Custom Serializers Override the default JSON serializer by binding your own:

    # config/services.yaml
    services:
        App\Serializer\DirectSerializer:
            tags: ['direct.serializer']
    
  2. Middleware Integration Add middleware to DirectBundle’s pipeline in config/packages/direct.yaml:

    direct:
        middleware:
            - App\DirectBundle\Middleware\AuthMiddleware
            - App\DirectBundle\Middleware\LoggingMiddleware
    
  3. Dynamic Action Mapping Register actions programmatically (e.g., for API versioning):

    use Atoermer\DirectBundle\Direct\DirectRegistry;
    
    public function __construct(private DirectRegistry $registry) {}
    
    public function boot() {
        $this->registry->addAction('v2.getUsers', [
            'controller' => [UserController::class, 'getUsersV2'],
            'params' => ['version' => ['type' => 'string', 'default' => 'v2']]
        ]);
    }
    

Performance Tips

  • Batch Processing Use Ext.data.Store with pageSize and start params to paginate:

    /**
     * @Direct(
     *     params={
     *         "page"={"type":"integer", "default":1},
     *         "limit"={"type":"integer", "default":20}
     *     }
     * )
     */
    public function getPaginatedUsers($page, $limit) {
        return $this->json([
            'data' => User::paginate($limit, ['*'], 'page', $page)->items(),
            'total' => User::count()
        ]);
    }
    
  • Caching Responses Cache frequent queries with Symfony’s cache component:

    use Symfony\Contracts\Cache\CacheInterface;
    
    public function __construct(private CacheInterface $cache) {}
    
    /**
     * @Direct()
     */
    public function getCachedData() {
        return $this->json($this->cache->get('direct_data', function() {
            return User::all()->toArray();
        }));
    }
    

Configuration Quirks

  • Routing Overrides DirectBundle’s direct.php route is non-negotiable. Avoid overriding it in custom routing files.

  • Parameter Naming DirectBundle uses `request->request->

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