Lewati ke konten utama

API Subresources di API Platform

API Platform mendukung fitur subresources, yaitu endpoint turunan dari entitas lain, misalnya: GET /api/users/1/comments

Fitur ini sangat berguna untuk menggambarkan relasi antar entitas (misal: satu User memiliki banyak Comment) secara RESTful dan otomatis.


1. Apa Itu Subresource?

Subresource adalah endpoint otomatis yang tersedia dari relasi antar entitas yang diberi anotasi #[ApiSubresource].

Contoh:

  • GET /api/authors/1/books
  • GET /api/categories/2/products

2. Contoh Kasus: User & Comment

Entitas User

use ApiPlatform\Metadata\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use ApiPlatform\Metadata\ApiSubresource;

#[ApiResource]
class User
{
#[ORM\OneToMany(mappedBy: 'user', targetEntity: Comment::class)]
#[ApiSubresource]
private Collection $comments;

public function __construct()
{
$this->comments = new ArrayCollection();
}

public function getComments(): Collection
{
return $this->comments;
}
}

Entitas Comment

#[ApiResource]
class Comment
{
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'comments')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
}

3. Hasil Endpoint

Dengan konfigurasi di atas, secara otomatis akan tersedia endpoint:

GET /api/users/{id}/comments

Yang akan mengembalikan semua komentar milik user dengan ID tertentu.

4. Pengaturan Pagination, Normalization

Kamu bisa menambahkan pengaturan khusus pada relasi subresource, misalnya:

#[ApiSubresource(maxDepth: 1)]

Atau menambahkan pengaturan context pada operasi GET:

#[ApiResource(
normalizationContext: ['groups' => ['comment:read']],
denormalizationContext: ['groups' => ['comment:write']]
)]

5. Filtering Subresource

Subresource juga bisa digunakan bersama filter. Misalnya:

GET /api/users/1/comments?order[createdAt]=desc

Pastikan filter diaktifkan di entitas target (Comment)`.

6. Membatasi Akses Subresource

Kamu bisa menggunakan security expression di ApiResource atau di operasi GET untuk membatasi siapa yang bisa mengakses:

#[ApiResource(
operations: [
new GetCollection(security: "is_granted('ROLE_ADMIN')")
]
)]

Atau di level global:

#[ApiSubresource]
#[Groups(['user:read'])]

7. Subresource Bukan Replace GET Utama

Endpoint /api/comments?user=/api/users/1 tetap tersedia, subresource hanya tambahan, bukan pengganti. Tapi lebih RESTful dan eksplisit.

8. Penting Diperhatikan

  • Gunakan #[ApiSubresource] di sisi relasi "parent" (OneToMany, ManyToMany)

  • Gunakan serialization group yang tepat agar data tersaji sesuai kebutuhan

  • Untuk menonaktifkan subresource default, hapus anotasi #[ApiSubresource]

  1. Contoh Response Request:
GET /api/users/1/comments

Response:

[
{
"@id": "/api/comments/10",
"content": "Komentar A"
},
{
"@id": "/api/comments/12",
"content": "Komentar B"
}
]

Kesimpulan ✅ Subresources mempermudah akses relasi antar entitas ✅ Menyediakan struktur URL RESTful dan intuitif ✅ Bisa digabung dengan filter, pagination, security ✅ Gunakan #[ApiSubresource] untuk mengaktifkan

🧩 Cocok untuk menyederhanakan frontend fetching seperti: user.comments, author.books, category.products, dll.