Installation:
composer require ekyna/api-bundle:^0.8
Register the bundle in config/bundles.php:
Ekyna\Bundle\ApiBundle\EkynaApiBundle::class => ['all' => true],
Basic Configuration:
Add the routing prefix in config/packages/ekyna_api.yaml:
ekyna_api:
routing_prefix: /api
First Use Case:
Extend an existing EkynaResourceBundle entity to expose API endpoints. For example, if you have a User entity managed by EkynaResourceBundle, the API endpoints (/api/users, /api/users/{id}) will be auto-generated.
Automatic CRUD Endpoints: The bundle leverages EkynaResourceBundle to auto-generate RESTful endpoints for entities. No manual controller creation is needed for basic CRUD operations.
# config/packages/ekyna_resource.yaml
ekyna_resource:
resources:
App\Entity\User:
collection: true
item: true
Customization via Annotations:
Use annotations to override default behavior (e.g., @Ekyna\Resource\Annotation\Api\ApiResource):
use Ekyna\Resource\Annotation\Api\ApiResource;
/**
* @ApiResource(
* collectionOperations={"get", "post"},
* itemOperations={"get", "put", "delete"}
* )
*/
class User {}
Serialization Groups: Use Symfony’s Serializer component with groups to control API payloads:
use Symfony\Component\Serializer\Annotation\Groups;
class User {
/**
* @Groups({"user:read"})
*/
private $name;
}
Custom Serializers: Extend the default serializer behavior by implementing Ekyna\Resource\Serializer\SerializerInterface and binding it in the container:
services:
App\Serializer\CustomUserSerializer:
tags: ['ekyna.resource.serializer']
JWT Integration: Pair with lexik/jwt-authentication-bundle for token-based auth. Configure the EkynaApiBundle to protect routes:
ekyna_api:
security:
enabled: true
provider: lexik_jwt_authentication.jwt_token_authenticator
Role-Based Access: Use Symfony’s voter system or EkynaResourceBundle’s @AccessControl annotation:
use Ekyna\Resource\Annotation\AccessControl;
/**
* @AccessControl("is_granted('ROLE_ADMIN')")
*/
class AdminUser {}
Default Pagination: Enable via config:
ekyna_api:
pagination:
enabled: true
items_per_page: 20
Custom Filters: Create a filter class and tag it as a ekyna.resource.filter service:
use Ekyna\Resource\Filter\FilterInterface;
class ActiveUserFilter implements FilterInterface {
// ...
}
services:
App\Filter\ActiveUserFilter:
tags: ['ekyna.resource.filter']
ekyna.resource.pre_collection or ekyna.resource.post_item:
use Ekyna\Resource\Event\ResourceEvent;
$eventDispatcher->addListener(ResourceEvent::PRE_COLLECTION, function (ResourceEvent $event) {
// Modify query or request before processing
});
Bundle Dependency:
EkynaApiBundle requires EkynaResourceBundle. Ensure both are installed and configured.EkynaResourceBundle is registered in config/bundles.php and properly configured.Routing Conflicts:
/api prefix may clash with other bundles (e.g., Symfony’s api_platform).routing_prefix or use a unique namespace:
ekyna_api:
routing_prefix: /v1
Serialization Mismatches:
@Groups).ekyna.resource.serializer tags).debug:container ekyna.resource.serializer to inspect registered serializers.Caching Issues:
EkynaResourceBundle’s cache invalidation:
framework:
cache:
pools: false # Disable for debugging
Annotation Overrides:
Ekyna\Resource\Annotation\AnnotationReader to inspect parsed annotations.Enable API Debug Mode:
ekyna_api:
debug: true # Logs requests/responses to Symfony profiler
Inspect Events:
/_profiler) to trace Ekyna\Resource\Event listeners.Check Route Generation:
php bin/console debug:router | grep ekyna
Custom API Platform:
EkynaApiBundle\Api\ApiPlatform by binding your implementation:
services:
App\Api\CustomApiPlatform:
decorates: 'ekyna.api.api_platform'
arguments: ['@.inner']
Dynamic Route Naming:
Ekyna\Resource\Routing\Router to customize route names:
use Ekyna\Resource\Routing\RouterInterface;
class CustomRouter implements RouterInterface {
public function generate(string $name, array $parameters = []): string {
// Custom logic
}
}
services:
App\Routing\CustomRouter:
decorates: 'ekyna.resource.router'
API Documentation:
nelmio/api-doc-bundle by extending the EkynaApiBundle’s documentation provider:
use Ekyna\Bundle\ApiBundle\Documentation\ApiDocumentation;
class CustomApiDocumentation extends ApiDocumentation {
public function getPaths(): array {
// Add custom paths
}
}
services:
App\Documentation\CustomApiDocumentation:
decorates: 'ekyna.api.documentation'
Priority in YAML vs. Annotations:
ekyna_api is global; annotations are per-entity. Annotations override YAML for specific cases.Security Provider:
security.enabled: true, ensure the provider (e.g., lexik_jwt_authentication.jwt_token_authenticator) is correctly configured in Symfony’s security.yaml.Pagination Defaults:
items_per_page applies to all collections unless overridden per-entity:
/**
* @ApiResource(
* paginationItemsPerPage=50
* )
*/
class LargeDataset {}
How can I help you explore Laravel packages today?