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

Dataloader Bundle Laravel Package

arxy/dataloader-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require overblog/dataloader-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        Overblog\DataLoaderBundle\OverblogDataLoaderBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration (config/packages/overblog_dataloader.yaml):

    overblog_dataloader:
        defaults:
            promise_adapter: "overblog_dataloader.react_promise_adapter"
        loaders:
            users:
                batch_load_fn: "@app.service.user:fetchUsers"
    
  3. First Use Case: Inject the loader into a service and use it to fetch batched data:

    use Overblog\DataLoaderBundle\DataLoader\DataLoaderInterface;
    
    class UserResolver
    {
        public function __construct(private DataLoaderInterface $usersLoader) {}
    
        public function resolveUser(int $id): mixed
        {
            return $this->usersLoader->load($id);
        }
    }
    

Implementation Patterns

1. Loader Configuration

  • Batch vs. Non-Batch: Use batch: true for batched queries (reduces N+1 queries).
    loaders:
        posts:
            batch_load_fn: "App\Service\PostService::fetchPosts"
            options:
                batch: true
                max_batch_size: 20
    
  • Caching: Enable caching with cache: true and specify a cache map:
    loaders:
        images:
            batch_load_fn: "App\Service\ImageService::fetchImages"
            options:
                cache: true
                cache_map: "app.cache.map"
    

2. Custom Factories

Create a custom factory for complex loader initialization:

loaders:
    custom_loader:
        factory: "App\Factory\CustomLoaderFactory"
        batch_load_fn: "@app.service.custom:loadData"

Factory class:

class CustomLoaderFactory
{
    public function __invoke(ContainerInterface $container): DataLoaderInterface
    {
        return new CustomLoader(
            $container->get('promise_adapter'),
            $container->get('custom_service')
        );
    }
}

3. Integration with GraphQL

  • Configure the promise adapter in overblog_graphql:
    overblog_graphql:
        services:
            promise_adapter: "webonyx_graphql.sync_promise_adapter"
    
  • Sync with DataLoaderBundle:
    overblog_dataloader:
        defaults:
            promise_adapter: "overblog_dataloader.webonyx_graphql_sync_promise_adapter"
    
  • Use in resolvers:
    public function resolveShip(int $id): mixed
    {
        return $this->container->get('ships_loader')->load($id);
    }
    

4. Dependency Injection

Autowire loaders directly:

class UserController
{
    public function __construct(
        private DataLoaderInterface $usersLoader,
        private DataLoaderInterface $postsLoader
    ) {}
}

Gotchas and Tips

Pitfalls

  1. Promise Adapter Mismatch:

    • Ensure the promise adapter (react, guzzle, or webonyx) matches the async library you’re using.
    • Example: Use react_promise_adapter for ReactPHP-based apps.
  2. Batch Load Function Signatures:

    • The batch_load_fn must return a Promise (or array in sync mode) of results.
    • Incorrect signatures cause silent failures. Test with:
      public function batchLoad(array $ids): array|PromiseInterface
      {
          return $this->repository->findBy(['id' => $ids]);
      }
      
  3. Caching Quirks:

    • If cache_map is misconfigured, the cache may not persist. Use a valid cache key function:
      options:
          cache_key_fn: "@app.cache:generateKey"
      
  4. Symfony 6+ Compatibility:

    • The bundle is designed for Symfony 2/3/4. For Symfony 6+, ensure autowiring is configured in config/services.yaml:
      Overblog\DataLoaderBundle\DataLoader\DataLoaderInterface: ~
      

Debugging Tips

  1. Log Promises: Wrap load() calls in a then() to inspect results:

    $this->usersLoader->load($id)->then(
        function ($user) { logger("Loaded: " . $user->getName()); }
    );
    
  2. Check Batch Sizes:

    • Monitor max_batch_size to avoid memory issues. Start with 10 and adjust.
  3. Clear Cache:

    • If loaders behave unexpectedly, clear the cache:
      php bin/console cache:clear
      

Extension Points

  1. Custom Promise Adapters: Extend the bundle by adding new adapters in config/packages/overblog_dataloader.yaml:

    services:
        overblog_dataloader.custom_promise_adapter:
            class: App\Promise\CustomAdapter
            tags: ['overblog_dataloader.promise_adapter']
    
  2. Dynamic Loaders: Create loaders programmatically in services:

    $loader = $this->container->get('overblog_dataloader.factory')->createLoader(
        'dynamic_loader',
        $batchLoadFn,
        ['batch' => true]
    );
    
  3. Testing: Mock DataLoaderInterface in tests:

    $mockLoader = $this->createMock(DataLoaderInterface::class);
    $mockLoader->method('load')->willReturn($expectedResult);
    
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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony