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

Symfony Laravel Package

api-platform/symfony

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require api-platform/symfony
    

    (Note: This is a read-only split of api-platform/core. Core functionality lives in api-platform/core.)

  2. Enable the Bundle In config/bundles.php, ensure:

    return [
        // ...
        ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
    ];
    
  3. First Use Case: Auto-Generated REST API

    • Annotate an entity with #[ApiResource]:
      use ApiPlatform\Metadata\ApiResource;
      
      #[ApiResource]
      class Book {
          #[ORM\Id]
          #[ORM\GeneratedValue]
          #[ORM\Column]
          public ?int $id = null;
      
          #[ORM\Column]
          public string $title;
      }
      
    • Run php bin/console debug:router to see auto-generated routes (e.g., /api/books, /api/books/{id}).
  4. Key Files to Review

    • config/packages/api_platform.yaml (default config).
    • src/Entity/ (annotate entities with #[ApiResource]).
    • config/routes/api_platform.yaml (custom route overrides).

Implementation Patterns

Core Workflows

1. Entity-Driven API Development

  • Pattern: Use #[ApiResource] on Doctrine/ODM entities to auto-generate CRUD endpoints.
    #[ApiResource(
        operations: [
            new Get(),
            new GetCollection(),
            new Post(denormalizationContext: ['groups' => ['book:write']]),
            new Put(),
            new Delete(),
        ],
        normalizationContext: ['groups' => ['book:read']],
        paginationItemsPerPage: 30,
    )]
    class Book { ... }
    
  • Tip: Group properties with #[Groups] for serialization control:
    use ApiPlatform\Metadata\ApiProperty;
    
    #[ApiProperty(groups: ['book:read'])]
    public string $title;
    
    #[ApiProperty(groups: ['book:write'])]
    public ?string $author = null;
    

2. Custom Operations

  • Pattern: Extend API with custom actions (e.g., #[Patch], #[DeleteCollection]).
    use ApiPlatform\Metadata\Operation;
    use ApiPlatform\State\ProcessorInterface;
    
    #[ApiResource]
    class Book {
        #[Operation(
            method: 'POST',
            uriTemplate: '/books/{id}/publish',
            controller: BookPublisher::class,
            input: BookPublishInput::class,
        )]
        public ?int $id = null;
    }
    
    // Controller
    class BookPublisher implements ProcessorInterface {
        public function __invoke(Book $data, Operation $operation, array $uriVariables): Book {
            $data->setPublished(true);
            // ...
            return $data;
        }
    }
    

3. GraphQL Integration

  • Pattern: Enable GraphQL with api-platform/graphql:
    composer require api-platform/graphql
    
  • Configure in config/packages/api_platform.yaml:
    api_platform:
        formats:
            jsonld: ['application/ld+json']
            jsonapi: ['application/vnd.api+json']
            graphql: ['application/graphql']
    
  • Query entities via GraphQL endpoint (/api/graphql):
    query {
      books {
        id
        title
      }
    }
    

4. Filtering and Pagination

  • Pattern: Use built-in filters (e.g., SearchFilter, OrderFilter):
    # config/packages/api_platform.yaml
    api_platform:
        formats:
            jsonapi: ['application/vnd.api+json']
        patch_formats:
            jsonapi: ['application/vnd.api+json']
        swagger:
            versions: [3]
        collection:
            pagination:
                items_per_page: 20
    
  • Dynamic Filters: Create custom filters:
    use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
    
    class PublishedFilter extends AbstractFilter {
        protected function filterProperty(string $property, $value, Iterable $queryBuilder, string $resourceClass, Operation $operation = null, array $context = []): void {
            if ($property === 'published' && $value === true) {
                $queryBuilder->andWhere('b.published = :val')->setParameter('val', true);
            }
        }
    }
    
    Register in api_platform.yaml:
    api_platform:
        filters:
            published: App\Filter\PublishedFilter
    

5. Security

  • Pattern: Secure endpoints with Symfony security:
    # config/packages/security.yaml
    access_control:
        - { path: ^/api/books, roles: ROLE_USER }
    
  • Custom Permissions: Use #[Security] on operations:
    #[ApiResource(
        operations: [
            new Get(security: "is_granted('ROLE_ADMIN')"),
        ]
    )]
    

6. Serialization Customization

  • Pattern: Override serialization with #[ApiProperty] or custom serializers:
    use ApiPlatform\Metadata\ApiProperty;
    use ApiPlatform\Metadata\ApiResource;
    
    #[ApiResource]
    class Book {
        #[ApiProperty(
            serializerContext: ['groups' => ['book:read']],
            denormalizerContext: ['groups' => ['book:write']]
        )]
        public string $title;
    }
    
  • Custom Serializer: Implement ApiPlatform\Serializer\SerializerContextBuilderInterface.

Integration Tips

  1. Doctrine ORM/ODM:

    • Ensure entities extend ApiPlatform\Metadata\ApiResource traits if needed.
    • Use api-platform/doctrine-orm for full ORM integration.
  2. Mercure (Real-Time Updates):

    • Install symfony/mercure-bundle and configure in api_platform.yaml:
      api_platform:
          mercure:
              hubs: ['https://your-mercure-hub']
      
  3. OpenAPI/Swagger:

    • Auto-generated docs at /api/doc. Customize with #[OpenApi] annotations:
      use ApiPlatform\Metadata\OpenApi;
      
      #[ApiResource(
          operations: [
              new Get(
                  openapi: new OpenApi(
                      summary: 'Get a book',
                      description: 'Returns a single book by ID',
                  ),
              ),
          ],
      )]
      
  4. Testing:

    • Use ApiPlatform\Bundle\Test\ApiTestCase for functional tests:
      use ApiPlatform\Bundle\Test\ApiTestCase;
      
      class BookTest extends ApiTestCase {
          public function testGetBooks(): void {
              $response = static::createClient()->request('GET', '/api/books');
              $this->assertResponseIsSuccessful();
          }
      }
      

Gotchas and Tips

Pitfalls

  1. Read-Only Repository:

    • Issues/PRs must be submitted to api-platform/core. This package is a Symfony-specific split.
  2. PHP Version Requirements:

    • Minimum PHP 8.2 (check composer.json). Downgrading may break dependencies.
  3. Serialization Conflicts:

    • Issue: Properties marked as #[Groups] may not serialize/deserialize as expected.
    • Fix: Ensure normalizationContext and denormalizationContext are consistent in #[ApiResource].
  4. Circular References:

    • Issue: Infinite loops in serialization (e.g., BookAuthor).
    • Fix: Use #[ApiProperty(serialize: false)] or configure max_depth in api_platform.yaml:
      api_platform:
          formats:
              jsonld:
                  max_depth: 3
      
  5. Doctrine Lifecycle Callbacks:

    • Issue: #[PrePersist], #[PostLoad] may interfere with API Platform’s state processors.
    • Fix: Use #[ApiResource] state options to control lifecycle:
      #[ApiResource(
          state: [
              new ProcessBookState(), // Custom state processor
          ],
      )]
      
  6. Pagination Quirks:

    • Issue: itemsPerPage in #[ApiResource] may conflict with global config.
    • Fix: Prioritize global config in api_platform.yaml over entity annotations.
  7. GraphQL Schema Conflicts:

    • Issue: Custom GraphQL types may clash with auto-generated schemas.
    • Fix: Use #[GraphQLName] to override field names or extend the schema via api_platform.graphql.schema.

Debugging Tips

  1. Enable Debug Mode:
    • Set APP_DEBUG=1 in .env to see detailed errors
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui