M
Mr Sugiarto
Developer
23 Aug 2026 3 min read

Semakin banyak data post yang tersimpan, endpoint GET /posts yang kita buat sejak Part 2 akan mengembalikan semua data sekaligus — tidak ideal untuk performa maupun pengalaman pengguna di sisi client. Di part ini kita akan menambahkan pagination dan fitur search sederhana ke endpoint tersebut.

Paginate di Goravel

Goravel menyediakan method Paginate langsung di query builder-nya:

Paginate(page, limit int, dest any, total *int64) error

Method ini otomatis menghitung OFFSET dan LIMIT yang dibutuhkan berdasarkan page dan limit, mengisi hasilnya ke dest, dan mengisi jumlah total data (tanpa limit) ke total.

Update Method Index

Ubah method Index di app/http/controllers/post_controller.go menjadi seperti berikut:

func (r *PostController) Index(ctx http.Context) http.Response {
	page, err := strconv.Atoi(ctx.Request().Input("page", "1"))
	if err != nil || page < 1 {
		page = 1
	}

	perPage, err := strconv.Atoi(ctx.Request().Input("per_page", "10"))
	if err != nil || perPage < 1 {
		perPage = 10
	}

	search := ctx.Request().Input("search", "")

	query := facades.Orm().Query()
	if search != "" {
		query = query.Where("title LIKE ?", "%"+search+"%")
	}

	var posts []models.Post
	var total int64
	if err := query.Paginate(page, perPage, &posts, &total); err != nil {
		return helpers.Error(ctx, http.StatusInternalServerError, "Failed to retrieve posts", err.Error())
	}

	lastPage := int(math.Ceil(float64(total) / float64(perPage)))

	return helpers.Success(ctx, http.StatusOK, "Posts retrieved successfully", http.Json{
		"posts": posts,
		"pagination": http.Json{
			"current_page": page,
			"per_page":     perPage,
			"total":        total,
			"last_page":    lastPage,
		},
	})
}

Beberapa poin penting:

  • page dan per_page diambil dari query parameter, dengan default 1 dan 10 kalau tidak dikirim.
  • search bersifat opsional — kalau diisi, kita tambahkan kondisi Where("title LIKE ?", "%"+search+"%") sebelum memanggil Paginate. Query builder Goravel bersifat chainable, jadi kondisi ini otomatis ikut dipakai saat Paginate dieksekusi.
  • Response data sekarang berisi dua bagian: posts (data aktual) dan pagination (meta info: halaman saat ini, jumlah per halaman, total data, dan total halaman). Format ini tetap konsisten dengan response envelope yang kita buat di Part 9.

Testing Endpoint

Coba beberapa variasi request berikut:

curl "http://127.0.0.1:3000/posts"
curl "http://127.0.0.1:3000/posts?page=2&per_page=5"
curl "http://127.0.0.1:3000/posts?search=goravel"

Perhatikan bagian pagination di response — current_page, per_page, total, dan last_page akan menyesuaikan dengan parameter yang dikirim dan jumlah data yang cocok dengan pencarian.

Penutup

Search yang kita buat di sini masih sederhana — hanya mencocokkan title. Untuk kebutuhan lebih lanjut, kondisi Where bisa dikembangkan lagi, misalnya ikut mencari di kolom body, atau ditambah filter berdasarkan status. Di part berikutnya kita akan membahas relasi antar model, mulai dari menghubungkan Post dengan User sebagai penulisnya (author).

M
Mr Sugiarto

Developer

Bagian dari Series: Seri Tutorial Belajar Framework Goravel Rest API untuk Pemula

Overview Seri ini membahas cara membangun REST API menggunakan Goravel, framework web berbasis Golang yang terinspirasi dari Laravel. Materi mencakup...

Lihat Series Lengkap