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 Pack Laravel Package

api-platform/api-pack

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require api-platform/api-pack
    

    Note: Only use v1.3.0 or earlier for Laravel compatibility. v1.4.0+ requires Symfony and is not recommended for vanilla Laravel projects.

  2. Publish Configuration:

    php artisan vendor:publish --provider="ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle"
    

    Warning: This may fail in Laravel due to Symfony-specific config structure. Use config/merge.php as a workaround.

  3. First Use Case: Create a resource class with API Platform annotations:

    // app/Entity/Book.php
    use ApiPlatform\Core\Annotation\ApiResource;
    
    #[ApiResource]
    class Book
    {
        #[ORM\Id]
        #[ORM\GeneratedValue]
        #[ORM\Column]
        private ?int $id = null;
    
        #[ORM\Column(length: 255)]
        public string $title;
    }
    

    Laravel Note: Ensure Doctrine ORM is installed (composer require doctrine/orm) and configured.

  4. Route Integration: Add to routes/api.php:

    Route::prefix('api')->group(function () {
        // Delegate to API Platform's router (requires middleware)
        Route::get('/books', [\App\Http\Controllers\ApiPlatformController::class, 'index']);
    });
    

    Workaround: Create a custom controller to bridge Laravel/Symfony routing.


Implementation Patterns

Usage Patterns

  1. Resource-Oriented Development:

    • Pattern: Use #[ApiResource] on Eloquent models to auto-generate REST/GraphQL endpoints.
    • Example:
      #[ApiResource(
          operations: ['get', 'post'],
          normalizationContext: ['groups' => ['book:read']],
          denormalizationContext: ['groups' => ['book:write']]
      )]
      class Book {}
      
    • Laravel Tip: Combine with Laravel’s policy system for authorization:
      #[ApiResource(security: "is_granted('view', object)")]
      
  2. State Providers for Business Logic:

    • Pattern: Offload complex logic (e.g., validation, pre-processing) to state providers.
    • Example:
      use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
      use ApiPlatform\Core\DataTransformer\ItemDataTransformerInterface;
      
      class BookStateProvider implements ItemDataTransformerInterface
      {
          public function transform($object, string $to, array $context = [])
          {
              if ($object->title === 'Banned Book') {
                  throw new \RuntimeException('Title not allowed');
              }
              return $object;
          }
      }
      
    • Register in config/api_platform.yaml (Symfony) or via Laravel service provider.
  3. Hybrid API Design:

    • Pattern: Mix REST (Laravel) and GraphQL (API Platform) under one domain.
    • Example:
      • Use Laravel’s Route::apiResource() for simple CRUD.
      • Use #[ApiResource(type: 'graphql')] for complex queries.
    • Laravel Integration:
      Route::prefix('graphql')->group(function () {
          Route::post('', [\App\Http\Controllers\GraphQLController::class, 'handle']);
      });
      
  4. Mercure for Real-Time Updates:

    • Pattern: Enable Mercure to push updates to clients.
    • Example:
      use ApiPlatform\Core\Annotation\MercureUBO;
      
      #[ApiResource]
      #[MercureUBO]
      class Book {}
      
    • Laravel Setup:
      composer require dunglas/mercure-bundle
      
      Configure .env:
      MERCURE_URL=http://mercure/.well-known/mercure
      MERCURE_PUBLIC_URL=https://yourdomain.com/.well-known/mercure
      MERCURE_JWT_SECRET=your-secret
      
  5. Validation Groups:

    • Pattern: Use Symfony’s validation groups for context-aware validation.
    • Example:
      use Symfony\Component\Validator\Constraints as Assert;
      
      class Book
      {
          #[Assert\NotBlank(groups: ['create'])]
          public string $title;
      
          #[Assert\NotBlank(groups: ['update'])]
          public string $author;
      }
      
    • Trigger in API Platform:
      # config/api_platform.yaml
      validation_context:
          groups: ['create']
      

Workflows

  1. Development Workflow:

    • Step 1: Scaffold a resource:
      php artisan make:entity Book --api
      
    • Step 2: Add annotations to the entity.
    • Step 3: Test with:
      php artisan api:docs:open
      
    • Laravel Note: Use php artisan route:list to verify routes.
  2. Testing:

    • Unit Tests: Mock API Platform services:
      $this->partialMockBuilder(ApiPlatform\Core\Bridge\Symfony\Serializer\SerializerContextBuilder::class)
           ->disableOriginalConstructor()
           ->getMock();
      
    • Integration Tests: Use Laravel’s Http::fake() to test API responses:
      $response = Http::get('/api/books');
      $response->assertJson([...]);
      
  3. Deployment:

    • Symfony Conflicts: Ensure bootstrap/cache is cleared:
      php artisan cache:clear
      php artisan config:clear
      
    • Mercure: Deploy Mercure hub separately (e.g., Docker):
      # docker-compose.yml
      mercure:
        image: dunglas/mercure
        ports:
          - "3000:3000"
      

Integration Tips

  1. Laravel-Symfony Bridge:

    • Create a facade to wrap Symfony services:
      // app/Facades/ApiPlatform.php
      namespace App\Facades;
      
      use Illuminate\Support\Facades\Facade;
      
      class ApiPlatform extends Facade
      {
          protected static function getFacadeAccessor() { return 'api_platform'; }
      }
      
    • Register in AppServiceProvider:
      $this->app->singleton('api_platform', function () {
          return new \ApiPlatform\Core\Bridge\Symfony\ApiPlatform(new \Symfony\Component\HttpKernel\HttpKernel());
      });
      
  2. Doctrine ORM:

    • Ensure config/database.php includes Doctrine:
      'connections' => [
          'default' => [
              'driver' => 'pdo_mysql',
              // ...
          ],
          'doctrine' => [
              'driver' => 'pdo_mysql',
              'url' => env('DATABASE_URL'),
              'host' => env('DB_HOST', '127.0.0.1'),
              // ...
          ],
      ],
      
    • Configure in config/api_platform.yaml:
      doctrine: ~
      
  3. Authentication:

    • Use Laravel’s auth system with API Platform:
      #[ApiResource(security: "is_granted('ROLE_USER')")]
      class Book {}
      
    • Create a custom guard:
      use ApiPlatform\Core\Bridge\Symfony\Security\UserCheckerInterface;
      
      class LaravelUserChecker implements UserCheckerInterface
      {
          public function checkPostLoad(UserInterface $user): void
          {
              if (!$user instanceof \App\Models\User) {
                  throw new \RuntimeException('Invalid user class');
              }
          }
      }
      
  4. Custom Serialization:

    • Extend API Platform’s serializer:
      use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
      
      class CustomSerializerContextBuilder implements SerializerContextBuilderInterface
      {
          public function createFromRequest(Request $request): array
          {
              $context = parent::createFromRequest($request);
              $context['groups'][] = 'custom_group';
              return $context;
          }
      }
      
    • Bind in AppServiceProvider:
      $this->app->bind(SerializerContextBuilderInterface::class, CustomSerializerContextBuilder::class);
      

Gotchas and Tips

Pitfalls

  1. Symfony Dependency Conflicts:

    • Pitfall: v1.4.0+ requires Symfony’s HttpKernel, which clashes with Laravel’s Illuminate\Foundation\HttpKernel.
    • Fix: Use v1.3.0 or fork the package to remove Symfony dependencies.
  2. Routing Conflicts:

    • Pitfall: API Platform’s router may override Laravel’s routes.
    • Fix: Namespace API Platform routes:
      Route::prefix('api')->group(function () {
          Route::get('/books', [ApiPlatformController::class, 'index'])->name('api.books');
      });
      
  3. Service Container Issues:

    • **P
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
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