API Platform dengan Symfony 2026: Arsitektur Modern dan Pertanyaan Wawancara

Panduan lengkap API Platform dengan Symfony di 2026, membahas arsitektur SmartPlatform, State Providers, custom filters, dan pertanyaan wawancara teknis untuk developer.

API Platform dengan Symfony 2026: Arsitektur Modern dan Pertanyaan Wawancara

API Platform telah menjadi standar de facto untuk membangun REST dan GraphQL API dengan Symfony. Di tahun 2026, framework ini menghadirkan SmartPlatform, sebuah evolusi yang membawa kemampuan AI-assisted development dan optimasi performa otomatis. Artikel ini membahas arsitektur modern API Platform, implementasi praktis, serta pertanyaan wawancara yang sering muncul untuk posisi Symfony developer.

API Platform 4.x memperkenalkan SmartPlatform yang mengintegrasikan caching prediktif dan auto-optimization query berdasarkan pola penggunaan API.

Arsitektur API Platform di 2026

API Platform dibangun di atas komponen Symfony dan mengikuti arsitektur yang clean serta mudah di-extend. Berikut adalah struktur dasar sebuah API resource:

php
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Delete;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ApiResource(
    operations: [
        new GetCollection(),
        new Get(),
        new Post(security: "is_granted('ROLE_ADMIN')"),
        new Put(security: "is_granted('ROLE_ADMIN') or object.owner == user"),
        new Delete(security: "is_granted('ROLE_ADMIN')")
    ],
    paginationItemsPerPage: 20,
    paginationClientEnabled: true
)]
class Product
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    #[Assert\NotBlank]
    #[Assert\Length(min: 3, max: 255)]
    private string $name;

    #[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
    #[Assert\Positive]
    private string $price;

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $description = null;

    #[ORM\ManyToOne(targetEntity: User::class)]
    public ?User $owner = null;

    // Getters and setters
    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;
        return $this;
    }

    public function getPrice(): string
    {
        return $this->price;
    }

    public function setPrice(string $price): self
    {
        $this->price = $price;
        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;
        return $this;
    }
}

SmartPlatform: Fitur Cerdas API Platform 4.x

SmartPlatform merupakan layer intelligence yang ditambahkan di API Platform versi terbaru. Fitur ini menganalisis pattern request dan mengoptimasi respons secara otomatis:

php
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\SmartPlatform\Attributes\SmartCache;
use ApiPlatform\SmartPlatform\Attributes\QueryOptimization;

#[ApiResource]
#[SmartCache(
    predictiveEnabled: true,
    learningMode: 'adaptive',
    ttlStrategy: 'usage_based'
)]
#[QueryOptimization(
    autoJoin: true,
    selectOptimization: true,
    indexSuggestions: true
)]
class Order
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: Customer::class)]
    #[ORM\JoinColumn(nullable: false)]
    private Customer $customer;

    #[ORM\OneToMany(mappedBy: 'order', targetEntity: OrderItem::class, cascade: ['persist'])]
    private Collection $items;

    #[ORM\Column(type: 'datetime_immutable')]
    private \DateTimeImmutable $createdAt;

    #[ORM\Column(length: 50)]
    private string $status = 'pending';
}

State Providers dan State Processors

API Platform 4.x menggunakan State Providers untuk mengambil data dan State Processors untuk menyimpan atau memanipulasi data. Pendekatan ini memberikan fleksibilitas tinggi:

php
<?php

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Repository\ProductRepository;
use App\Entity\Product;

class ProductStateProvider implements ProviderInterface
{
    public function __construct(
        private ProductRepository $repository,
        private CacheInterface $cache
    ) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        if ($operation instanceof GetCollection) {
            return $this->repository->findActiveProducts(
                $context['filters'] ?? []
            );
        }

        $id = $uriVariables['id'] ?? null;
        
        return $this->cache->get(
            "product_{$id}",
            fn() => $this->repository->find($id)
        );
    }
}

State Processor menangani operasi tulis dengan clean separation:

php
<?php

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\MessageBusInterface;

class ProductStateProcessor implements ProcessorInterface
{
    public function __construct(
        private EntityManagerInterface $em,
        private MessageBusInterface $bus
    ) {}

    public function process(
        mixed $data,
        Operation $operation,
        array $uriVariables = [],
        array $context = []
    ): Product {
        if ($operation instanceof Post) {
            $data->setCreatedAt(new \DateTimeImmutable());
        }

        $this->em->persist($data);
        $this->em->flush();

        $this->bus->dispatch(new ProductUpdatedMessage($data->getId()));

        return $data;
    }
}

Custom Filters untuk Query Kompleks

API Platform menyediakan sistem filter yang powerful untuk membangun query kompleks:

php
<?php

namespace App\Filter;

use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\QueryBuilder;

class ProductAvailabilityFilter extends AbstractFilter
{
    protected function filterProperty(
        string $property,
        mixed $value,
        QueryBuilder $queryBuilder,
        QueryNameGeneratorInterface $queryNameGenerator,
        string $resourceClass,
        Operation $operation = null,
        array $context = []
    ): void {
        if ($property !== 'availability') {
            return;
        }

        $alias = $queryBuilder->getRootAliases()[0];
        $paramName = $queryNameGenerator->generateParameterName($property);

        match ($value) {
            'in_stock' => $queryBuilder
                ->andWhere("$alias.stock > 0"),
            'out_of_stock' => $queryBuilder
                ->andWhere("$alias.stock = 0"),
            'low_stock' => $queryBuilder
                ->andWhere("$alias.stock > 0")
                ->andWhere("$alias.stock < :threshold")
                ->setParameter('threshold', 10),
            default => null
        };
    }

    public function getDescription(string $resourceClass): array
    {
        return [
            'availability' => [
                'property' => 'availability',
                'type' => 'string',
                'required' => false,
                'description' => 'Filter by stock availability',
                'openapi' => [
                    'enum' => ['in_stock', 'out_of_stock', 'low_stock']
                ]
            ]
        ];
    }
}

Serialization Groups dan Data Transfer Objects

Menggunakan serialization groups memungkinkan kontrol presisi atas data yang diekspos:

php
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use Symfony\Component\Serializer\Annotation\Groups;

#[ApiResource(
    operations: [
        new GetCollection(normalizationContext: ['groups' => ['product:list']]),
        new Get(normalizationContext: ['groups' => ['product:read', 'product:details']])
    ]
)]
class Product
{
    #[Groups(['product:list', 'product:read'])]
    private ?int $id = null;

    #[Groups(['product:list', 'product:read'])]
    private string $name;

    #[Groups(['product:list', 'product:read'])]
    private string $price;

    #[Groups(['product:details'])]
    private ?string $description = null;

    #[Groups(['product:details'])]
    private Collection $reviews;
}

DTO pattern untuk input yang kompleks:

php
<?php

namespace App\Dto;

use Symfony\Component\Validator\Constraints as Assert;

class CreateOrderInput
{
    #[Assert\NotBlank]
    public int $customerId;

    #[Assert\NotBlank]
    #[Assert\Count(min: 1)]
    #[Assert\Valid]
    public array $items;

    #[Assert\NotBlank]
    public string $shippingAddress;

    public ?string $notes = null;
}

Pertanyaan Wawancara API Platform Symfony

Berikut adalah pertanyaan wawancara yang sering diajukan untuk posisi Symfony developer dengan fokus API Platform:

Pertanyaan Level Junior

Apa perbedaan antara ApiResource attribute dan konfigurasi YAML?

Kedua metode memberikan hasil yang sama, namun attribute lebih disukai karena mendukung IDE autocompletion dan menjaga konfigurasi dekat dengan entity. YAML berguna untuk konfigurasi yang perlu diubah tanpa mengubah kode.

Bagaimana cara mengimplementasikan pagination di API Platform?

Pagination diaktifkan secara default. Konfigurasi dapat dilakukan melalui attribute ApiResource dengan properti paginationItemsPerPage dan paginationClientEnabled untuk memungkinkan client mengontrol jumlah item.

Pertanyaan Level Menengah

Jelaskan lifecycle State Provider dan State Processor.

State Provider dipanggil untuk operasi GET untuk mengambil data dari sumber apapun. State Processor menangani operasi POST, PUT, PATCH, dan DELETE. Keduanya dapat di-chain dan memungkinkan transformasi data sebelum atau sesudah operasi utama.

Bagaimana mengimplementasikan custom authentication untuk API?

php
<?php

namespace App\Security;

use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;

class ApiTokenHandler implements AccessTokenHandlerInterface
{
    public function __construct(
        private UserRepository $userRepository,
        private TokenValidatorService $tokenValidator
    ) {}

    public function getUserBadgeFrom(string $accessToken): UserBadge
    {
        $tokenData = $this->tokenValidator->validate($accessToken);
        
        return new UserBadge(
            $tokenData->getUserIdentifier(),
            fn(string $id) => $this->userRepository->find($id)
        );
    }
}

Pertanyaan Level Senior

Bagaimana mengoptimasi performa API untuk high-traffic scenarios?

Optimasi mencakup implementasi HTTP caching dengan proper cache headers, menggunakan Varnish sebagai reverse proxy, mengimplementasi database query optimization dengan proper indexing, menggunakan async processing dengan Symfony Messenger untuk operasi berat, dan memanfaatkan SmartPlatform untuk predictive caching.

Jelaskan strategi versioning API yang Anda rekomendasikan.

URI versioning (/api/v1/) cocok untuk perubahan besar, header versioning (Accept: application/vnd.api+json;version=1) lebih RESTful, dan evolution strategy dengan backward compatibility untuk perubahan minor. API Platform mendukung semua pendekatan ini melalui custom operations dan routing.

Siap menguasai wawancara Symfony Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Kesimpulan

API Platform dengan Symfony di 2026 menawarkan solusi lengkap untuk membangun API modern. SmartPlatform membawa intelligence layer yang mengoptimasi performa secara otomatis, sementara arsitektur yang bersih dengan State Providers dan Processors memberikan fleksibilitas maksimal. Pemahaman mendalam tentang fitur-fitur ini sangat penting untuk interview teknis dan untuk membangun API yang scalable dalam production. Developer yang menguasai API Platform akan memiliki keunggulan kompetitif di pasar kerja Symfony 2026.

Tantangan harian

Bisakah kamu menemukan bug di Symfony?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 8 September 2026

Bagikan

Artikel terkait