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

Api Base Bundle Laravel Package

braune-digital/api-base-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies Run:

    composer require braune-digital/api-base-bundle "1.*" fos/rest-bundle white-october/pagerfanta-bundle fos/user-bundle jms/serializer-bundle
    

    Ensure AppKernel.php includes:

    new FOS\RestBundle\FOSRestBundle(),
    new BrauneDigital\ApiBaseBundle\BrauneDigitalApiBaseBundle(),
    
  2. Configure config.yml

    braune_digital_api_base:
        modules:
            module1: [ROLE_USER]  # Role-based module access
            module2: [ROLE_ADMIN]
        timeout: 3600            # Token expiry in seconds (0 = no expiry)
        configuration:
            app_version: "1.0.0"
            environment: "production"
    
  3. First Use Case: Extend BaseApiController Create a controller:

    use BrauneDigital\ApiBaseBundle\Controller\BaseApiController;
    
    class UserController extends BaseApiController
    {
        public function getUsersAction()
        {
            return $this->handleList(new User(), [
                'fields' => ['id', 'name', 'email'],
                'page' => $this->get('request')->query->get('page', 1),
            ]);
        }
    }
    
  4. Route the Controller

    # app/config/routing.yml
    user_api:
        resource: "@YourBundle/Resources/config/routing.yml"
        type: rest
    

Implementation Patterns

1. BaseApiController Workflow

  • List Handling: Use handleList() for paginated collections:
    $this->handleList($entityClass, [
        'filter' => ['active' => true],
        'sort' => ['name' => 'ASC'],
    ]);
    
  • Single Item Handling: Use handleGet():
    $this->handleGet($entityClass, $id);
    
  • Custom Responses: Override getConfiguration() to merge bundle config:
    protected function getConfiguration()
    {
        return array_merge(parent::getConfiguration(), [
            'custom_field' => 'value',
        ]);
    }
    

2. API Key Authentication

  • Generate Tokens: Use FOSUser’s api_token field (extend User entity if needed).
  • Validate Tokens: The bundle auto-validates via ROLE_API in security.yml:
    security:
        providers:
            fos_userbundle:
                id: fos_user.user_provider.username_email
        firewalls:
            api:
                pattern: ^/api
                stateless: true
                anonymous: false
                provider: fos_userbundle
                fos_rest: ~
    

3. Module-Based Access Control

  • Define Modules: Configure in braune_digital_api_base.modules (YAML).
  • Restrict Routes: Use annotations or YAML:
    _api_module:
        path: /module1
        defaults: { _controller: YourBundle:User:module1Action }
        requirements:
            _role: ROLE_USER
    

4. Pagination

  • Auto-Pagination: handleList() integrates WhiteOctoberPagerfantaBundle:
    $this->handleList(User::class, [
        'page' => 2,
        'limit' => 10,
    ]);
    
  • Customize Pagination: Override getPagerfantaAdapter() in your controller.

5. Query Filtering (Planned Feature)

  • Future-Proofing: Prepare for dynamic filters by extending BaseApiController:
    protected function getFilterCriteria()
    {
        return $this->get('request')->query->all();
    }
    

Gotchas and Tips

Pitfalls

  1. Deprecated Dependencies

    • FOSRestBundle: Ensure compatibility with your Symfony version (v1.x is old; test thoroughly).
    • JMSSerializerBundle: Optional but recommended for complex responses. Conflicts may arise with Symfony’s native serializer.
  2. Token Timeout

    • timeout: 0 disables expiry, which is insecure for production. Use a realistic value (e.g., 3600 for 1 hour).
  3. Module Access Overrides

    • Module roles are OR-based by default. To enforce AND, override checkModuleAccess():
      public function checkModuleAccess($module, User $user)
      {
          if (!parent::checkModuleAccess($module, $user)) {
              return false;
          }
          return $user->hasRole('ROLE_SUPER_ADMIN');
      }
      
  4. CSRF Exemption

    • disable_csrf_role: ROLE_API must be set in fos_rest config. Forgetting this causes 403 errors on POST/PUT.
  5. Pagination Edge Cases

    • Empty results may return null instead of an empty array. Normalize in your controller:
      $data = $this->handleList(...);
      return $data ?: ['data' => []];
      

Debugging Tips

  1. Token Validation

    • Check ROLE_API is assigned to the user entity. Debug with:
      $this->get('security.token_storage')->getToken()->getUser()->getRoles();
      
  2. Configuration Merging

    • Override getConfiguration() to inspect merged values:
      dump($this->getConfiguration());
      
  3. Query Filtering (Placeholder)

    • Monitor the repo for updates. For now, manually filter in handleList():
      $queryBuilder->andWhere('u.active = :active')->setParameter('active', true);
      

Extension Points

  1. Custom Serialization

    • Extend BaseApiController to modify serialization:
      protected function customizeSerializer()
      {
          $serializer = $this->get('jms_serializer');
          $serializer->configureHandlers(function (HandlerRegistry $registry) {
              $registry->getOrCreateHandlerFor('Your\Entity', 'json')->setSerializationVisitor(...);
          });
      }
      
  2. Dynamic Module Loading

    • Load modules dynamically via a service:
      braune_digital_api_base:
          modules: "@=service('your_service').getModules()"
      
  3. Event Listeners

    • Subscribe to api.base.response events to modify responses globally:
      $dispatcher->addListener('api.base.response', function (ResponseEvent $event) {
          $event->getResponse()->headers->set('X-Custom-Header', 'value');
      });
      
  4. Legacy Support

    • For Symfony 4/5, wrap the bundle in a bridge or fork to update dependencies. Example:
      // composer.json
      "repositories": [
          {
              "type": "vcs",
              "url": "https://github.com/braune-digital/BrauneDigitalApiBaseBundle"
          }
      ],
      "extra": {
          "symfony-endpoint": "https://api.github.com/repos/braune-digital/BrauneDigitalApiBaseBundle"
      }
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
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
spatie/mailcoach-vapor