Study
Play Framework

Async Action (Future-based)

Penjelasan

Ketika logic di dalam Action melibatkan operasi yang mengembalikan `Future` (query database via Slick, panggilan HTTP ke service lain, dll), `Action.async` dipakai alih-alih `Action` biasa. Bedanya, blok di dalam `Action.async` harus mengembalikan `Future[Result]`, bukan `Result` langsung — Play menunggu Future tersebut selesai secara non-blocking sebelum mengirim response ke klien. Pola ini penting untuk menjaga thread pool Play tetap efisien: karena Future diproses secara non-blocking, thread yang menangani request tidak "diam menunggu" operasi lambat selesai, melainkan bisa dipakai untuk melayani request lain sementara menunggu. Composisi beberapa Future (misalnya query database lalu panggil API eksternal) dilakukan lewat `map`/`flatMap` atau for-comprehension seperti Future biasa di Scala.

Contoh Konsep

import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}
import javax.inject._

@Singleton
class ProdukController @Inject()(cc: ControllerComponents, produkService: ProdukService)(implicit ec: ExecutionContext)
  extends AbstractController(cc) {

  def daftar(): Action[AnyContent] = Action.async {
    produkService.ambilSemuaAsync().map { produkList =>
      Ok(produkList.mkString(", "))
    }
  }
}

Praktikum

Buat Action.async detail(id: Long) yang memanggil produkService.cariByIdAsync(id): Future[Option[String]], mengembalikan Ok jika ada, NotFound jika kosong.

Editor Latihan

Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.

Tips

Selalu pastikan ExecutionContext yang dipakai untuk Future berat (query database) memakai dispatcher terpisah dari default, mirip prinsip dispatcher tuning di Akka, agar operasi lambat tidak mengganggu request lain.