API Platform Symfony REST: คู่มือฉบับสมบูรณ์และคำถามสัมภาษณ์ 2026
คู่มือเต็มรูปแบบ API Platform Symfony สำหรับสร้าง REST API สมัยใหม่ เรียนรู้การติดตั้ง การกำหนดค่า การดำเนินการ CRUD และคำถามสัมภาษณ์ 2026

API Platform เป็น framework PHP ที่ได้รับความนิยมมากที่สุดสำหรับการสร้าง API สมัยใหม่บน Symfony โดย framework นี้มีฟีเจอร์พร้อมใช้งานมากมาย เช่น เอกสาร OpenAPI, การแบ่งหน้า, การกรองข้อมูล และการตรวจสอบความถูกต้อง บทความนี้อธิบายวิธีใช้ API Platform เพื่อสร้าง REST API ที่สามารถขยายขนาดได้และพร้อมสำหรับ production
API Platform 4.x นำเสนอ state providers และ processors ใหม่ที่มาแทนที่ data providers เดิม ควรใช้เวอร์ชันล่าสุดเพื่อรับฟีเจอร์สมัยใหม่ทั้งหมด
การติดตั้ง API Platform ใน Symfony
ขั้นตอนแรกคือการติดตั้ง API Platform โดยใช้ Composer โดย framework นี้รวมเข้ากับ Symfony 7 ได้อย่างสมบูรณ์แบบและมี bundle พร้อมใช้งาน
composer create-project symfony/skeleton my-api
cd my-api
composer require apiหลังจากติดตั้งแล้ว API Platform จะกำหนดค่า routes และเอกสารโดยอัตโนมัติ การกำหนดค่าพื้นฐานสามารถพบได้ในไฟล์ config/packages/api_platform.yaml
# config/packages/api_platform.yaml
api_platform:
title: 'My API'
version: '1.0.0'
formats:
jsonld: ['application/ld+json']
json: ['application/json']
defaults:
stateless: true
cache_headers:
vary: ['Content-Type', 'Authorization', 'Origin']
swagger:
versions: [3]การสร้าง Resource API แรก
API Platform ใช้ PHP attributes เพื่อกำหนด resources โดยทุก entity ที่มี #[ApiResource] จะได้รับ endpoints CRUD โดยอัตโนมัติ
<?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(),
new Put(),
new Delete()
],
paginationItemsPerPage: 20
)]
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: 'text')]
private string $description;
#[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
#[Assert\Positive]
private string $price;
#[ORM\Column]
private \DateTimeImmutable $createdAt;
public function __construct()
{
$this->createdAt = new \DateTimeImmutable();
}
// Getters and setters...
}การกรองและการเรียงลำดับข้อมูล
API Platform มีตัวกรองในตัวหลายตัวที่สามารถเปิดใช้งานได้ง่าย ตัวกรองช่วยให้ client สามารถ query ข้อมูลตามเกณฑ์ที่กำหนด
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Doctrine\Orm\Filter\RangeFilter;
use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ApiResource]
#[ApiFilter(SearchFilter::class, properties: [
'name' => 'partial',
'description' => 'partial',
'category.name' => 'exact'
])]
#[ApiFilter(OrderFilter::class, properties: ['name', 'price', 'createdAt'])]
#[ApiFilter(RangeFilter::class, properties: ['price'])]
#[ApiFilter(DateFilter::class, properties: ['createdAt'])]
class Product
{
// Properties...
}ตัวอย่างการ query โดยใช้ตัวกรอง:
# ค้นหาสินค้าที่มีชื่อประกอบด้วย "laptop"
GET /api/products?name=laptop
# กรองตามช่วงราคา
GET /api/products?price[gte]=100&price[lte]=500
# เรียงลำดับตามราคาจากมากไปน้อย
GET /api/products?order[price]=descการตรวจสอบความถูกต้องและ Serialization Groups
การตรวจสอบความถูกต้องใน API Platform ใช้ Symfony Validator component โดย Serialization groups ช่วยให้ควบคุมข้อมูลที่ส่งกลับได้อย่างละเอียด
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
#[ApiResource(
normalizationContext: ['groups' => ['product:read']],
denormalizationContext: ['groups' => ['product:write']],
operations: [
new GetCollection(normalizationContext: ['groups' => ['product:list']]),
new Get(normalizationContext: ['groups' => ['product:read', 'product:detail']]),
new Post()
]
)]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['product:read', 'product:list'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Assert\NotBlank(message: 'Product name is required')]
#[Groups(['product:read', 'product:list', 'product:write'])]
private string $name;
#[ORM\Column(type: 'text')]
#[Groups(['product:read', 'product:detail', 'product:write'])]
private string $description;
#[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
#[Assert\Positive(message: 'Price must be positive')]
#[Groups(['product:read', 'product:list', 'product:write'])]
private string $price;
// Getters and setters...
}State Providers และ Processors
API Platform 4 นำเสนอ State Providers และ Processors สำหรับ custom logic ซึ่งมาแทนที่ Data Providers และ Data Persisters จากเวอร์ชันก่อนหน้า
<?php
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Repository\ProductRepository;
class ProductStateProvider implements ProviderInterface
{
public function __construct(
private ProductRepository $repository
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
if (isset($uriVariables['id'])) {
return $this->repository->find($uriVariables['id']);
}
return $this->repository->findActiveProducts();
}
}State Processor สำหรับ custom logic เมื่อบันทึกข้อมูล:
<?php
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Mailer\MailerInterface;
class ProductProcessor implements ProcessorInterface
{
public function __construct(
private EntityManagerInterface $em,
private MailerInterface $mailer
) {}
public function process(
mixed $data,
Operation $operation,
array $uriVariables = [],
array $context = []
): mixed {
$this->em->persist($data);
$this->em->flush();
// Send notification email
$this->sendNotification($data);
return $data;
}
private function sendNotification(object $product): void
{
// Email logic...
}
}การยืนยันตัวตนและการอนุญาต
API Platform รวมเข้ากับ Symfony Security สำหรับการยืนยันตัวตน JWT หรือ API token
# config/packages/security.yaml
security:
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~
access_control:
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
- { path: ^/api/products, roles: PUBLIC_ACCESS, methods: [GET] }
- { path: ^/api, roles: ROLE_USER }การใช้ security ในระดับ resource:
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Delete;
#[ApiResource(
operations: [
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Delete(
security: "is_granted('ROLE_ADMIN') or object.owner == user",
securityMessage: "Only admin or owner can delete this resource"
)
]
)]
class Product
{
// Properties...
}การทดสอบ API Endpoints
การทดสอบ API เป็นสิ่งสำคัญเพื่อให้แน่ใจว่า endpoints ทำงานได้อย่างถูกต้อง Symfony มี WebTestCase สำหรับ functional testing
<?php
namespace App\Tests\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
class ProductApiTest extends ApiTestCase
{
private EntityManagerInterface $em;
protected function setUp(): void
{
$this->em = self::getContainer()->get('doctrine')->getManager();
}
public function testGetProducts(): void
{
$response = static::createClient()->request('GET', '/api/products');
$this->assertResponseIsSuccessful();
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
$this->assertJsonContains(['@type' => 'hydra:Collection']);
}
public function testCreateProduct(): void
{
$response = static::createClient()->request('POST', '/api/products', [
'json' => [
'name' => 'New Product',
'description' => 'Product description',
'price' => '99.99'
],
'headers' => [
'Authorization' => 'Bearer ' . $this->getToken()
]
]);
$this->assertResponseStatusCodeSame(201);
$this->assertJsonContains(['name' => 'New Product']);
}
public function testValidationError(): void
{
$response = static::createClient()->request('POST', '/api/products', [
'json' => [
'name' => '',
'price' => -10
]
]);
$this->assertResponseStatusCodeSame(422);
}
}คำถามสัมภาษณ์ API Platform 2026
ต่อไปนี้คือคำถามที่พบบ่อยในการสัมภาษณ์เกี่ยวกับ API Platform:
1. ความแตกต่างระหว่าง State Provider และ Data Provider คืออะไร?
State Provider เป็นแนวทางใหม่ใน API Platform 4 ที่มีความยืดหยุ่นมากขึ้น Data Provider ถูก deprecated และถูกแทนที่ด้วย State Provider ที่รองรับ async operations และ type safety ที่ดีขึ้น
2. จะ implement pagination แบบกำหนดเองได้อย่างไร?
Pagination สามารถปรับแต่งได้ผ่านการกำหนดค่า resource หรือโดยการสร้าง custom Paginator ที่ implement PaginatorInterface
3. อธิบายความแตกต่างระหว่าง normalization และ denormalization context?
Normalization context ใช้เมื่อข้อมูลถูกแปลงจาก object เป็น array/JSON (response) Denormalization context ใช้เมื่อข้อมูลถูกแปลงจาก JSON เป็น object (request)
4. จะจัดการความสัมพันธ์ใน API Platform ได้อย่างไร?
ความสัมพันธ์สามารถเปิดเผยเป็น IRI (reference) หรือ embedded object โดยใช้ serialization groups สำหรับการดำเนินการแบบซ้อน ใช้ subresource หรือ custom operations
5. OpenAPI คืออะไร และ API Platform ใช้มันอย่างไร?
OpenAPI (เดิมชื่อ Swagger) เป็นข้อกำหนดสำหรับเอกสาร API โดย API Platform จะสร้างเอกสาร OpenAPI โดยอัตโนมัติจาก metadata ของ resources
พร้อมที่จะพิชิตการสัมภาษณ์ Symfony แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
บทสรุป
API Platform มอบโซลูชันที่ครบถ้วนสำหรับการสร้าง REST API ด้วย Symfony ด้วยฟีเจอร์ต่างๆ เช่น การดำเนินการ CRUD อัตโนมัติ, การกรอง, การแบ่งหน้า และเอกสาร OpenAPI นักพัฒนาสามารถมุ่งเน้นไปที่ business logic โดยไม่ต้องเขียน boilerplate code ความเข้าใจอย่างลึกซึ้งเกี่ยวกับ State Providers, Processors และ serialization groups มีความสำคัญมากสำหรับการใช้ประโยชน์จาก API Platform อย่างเต็มที่ในโปรเจกต์ production
คุณหาบั๊กใน Symfony เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 25 สิงหาคม 2569
แชร์
บทความที่เกี่ยวข้อง

ความปลอดภัย REST API Symfony ปี 2026: OAuth2, Rate Limiting และคำถามสัมภาษณ์
เรียนรู้วิธีรักษาความปลอดภัย REST API Symfony ด้วย OAuth2 token introspection, rate limiting และการตรวจสอบ JWT ครอบคลุมฟีเจอร์ความปลอดภัย Symfony 7.3 ช่องโหว่ทั่วไป และคำถามสัมภาษณ์ทางเทคนิค

API Platform กับ Symfony 2026: สถาปัตยกรรมสมัยใหม่และคำถามสัมภาษณ์งาน
คู่มือครบถ้วนเกี่ยวกับ API Platform กับ Symfony ในปี 2026 ครอบคลุมสถาปัตยกรรม SmartPlatform, State Providers, custom filters และคำถามสัมภาษณ์ทางเทคนิคสำหรับนักพัฒนา

API Platform GraphQL Symfony: Schema, Mutation และคำถามสัมภาษณ์ 2026
คู่มือฉบับสมบูรณ์สำหรับการผสาน API Platform GraphQL กับ Symfony เรียนรู้ schema อัตโนมัติ mutation, custom resolver, ความปลอดภัย และคำถามสัมภาษณ์ทางเทคนิคสำหรับนักพัฒนา 2026