GoDasturchi
Pagination: Limit & Offset

Pagination: Limit & Offset

Sahifalash: Limit va Offset

Foto albomni varaqlaganda, hammasini BIR VARAQQA joylashtirmaysiz — har sahifada 10 tadan rasm, va "3-sahifa"ga o'tish uchun avvalgi 20 tasini O'TKAZIB YUBORASIZ. API'da ham xuddi shu ikki tushuncha bor: limit (bitta "sahifa"da nechta yozuv) va offset (nechta yozuvni O'TKAZIB YUBORISH). 10 ming kitobli katalogni BIR SO'ROVDA qaytarish — serverni ham, mijozni ham "cho'ktiradi"; limit/offset esa uni BOSHQARILADIGAN qismlarga bo'lib beradi.

example.go
package main

import (
	"fmt"
	"net/url"
	"strconv"
)

type Book struct {
	ID string
}

// parsePagination — query parametrlaridan limit/offset o'qiydi, OQILONA standartlar bilan
func parsePagination(q url.Values) (limit, offset int) {
	limit = 10
	offset = 0
	if v := q.Get("limit"); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n > 0 {
			limit = n
		}
	}
	if v := q.Get("offset"); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n >= 0 {
			offset = n
		}
	}
	if limit > 100 {
		limit = 100
	}
	return limit, offset
}

func paginate(books []*Book, limit, offset int) []*Book {
	if offset >= len(books) {
		return []*Book{}
	}
	end := offset + limit
	if end > len(books) {
		end = len(books)
	}
	return books[offset:end]
}

func main() {
	books := []*Book{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}

	q, _ := url.ParseQuery("limit=2&offset=2")
	limit, offset := parsePagination(q)
	page := paginate(books, limit, offset)
	for _, b := range page {
		fmt.Println(b.ID)
	}
}

parsePagination — HAR DOIM OQILONA STANDART qiymat bilan boshlanadi (limit=10, offset=0), va faqat TO'G'RI (musbat/manfiy bo'lmagan) qiymat kelsagina UNI qo'llaydi — noto'g'ri yoki bo'sh parametr dastur QULASHIGA emas, STANDART qiymatga olib keladi. if limit > 100 { limit = 100 } — mijoz limit=1000000 deb so'rasa ham, server O'ZINI himoya qiladi: bitta so'rov BUTUN bazani qaytarib yubormaydi.

paginate — Go slice'ining [offset:end] KESISH (slicing) amalidan foydalanadi ("Slices" darsini eslang): offset — qayerdan BOSHLASH, end — qayerda TO'XTASH. offset >= len(books) tekshiruvi — mijoz OXIRGI sahifadan HAM UZOQROQQA so'rov yuborsa (masalan offset=1000, atigi 5 ta yozuv bo'lsa), dastur QULAMASLIGINI ("index out of range" xatosisiz) ta'minlaydi.

>_ Exercise

Sahifalashni HAQIQIY HTTP endpoint'ga ulang va chegara holatlarini sinang.

  • "GET /books" handlerini yozing: r.URL.Query() orqali parsePagination va paginate'ni chaqirib, natijani JSON massiv qilib qaytaring
  • 150 ta kitobdan iborat ro'yxat yarating (strconv.Itoa(i) bilan ID'lar 1 dan 150 gacha)
  • "?limit=500" so'rovi yuboring — natija 100 tadan OSHMASLIGI kerak (chegaraga tortilgan)
  • "?offset=1000" so'rovi yuboring — natija BO'SH (0 ta) bo'lishi kerak
  • har ikki holatning natija UZUNLIGINI chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Limit/offset sahifalash — katta ro'yxatni BOSHQARILADIGAN qismlarga bo'ladi; server HAR DOIM limitga YUQORI CHEGARA qo'yishi va offset ro'yxat uzunligidan OSHIB ketgan holatni HISOBGA olishi kerak.

NEXT UP

Pagination: Cursor-Based

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Pagination: Limit & Offset

Sahifalash: Limit va Offset

Foto albomni varaqlaganda, hammasini BIR VARAQQA joylashtirmaysiz — har sahifada 10 tadan rasm, va "3-sahifa"ga o'tish uchun avvalgi 20 tasini O'TKAZIB YUBORASIZ. API'da ham xuddi shu ikki tushuncha bor: limit (bitta "sahifa"da nechta yozuv) va offset (nechta yozuvni O'TKAZIB YUBORISH). 10 ming kitobli katalogni BIR SO'ROVDA qaytarish — serverni ham, mijozni ham "cho'ktiradi"; limit/offset esa uni BOSHQARILADIGAN qismlarga bo'lib beradi.

example.go
package main

import (
	"fmt"
	"net/url"
	"strconv"
)

type Book struct {
	ID string
}

// parsePagination — query parametrlaridan limit/offset o'qiydi, OQILONA standartlar bilan
func parsePagination(q url.Values) (limit, offset int) {
	limit = 10
	offset = 0
	if v := q.Get("limit"); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n > 0 {
			limit = n
		}
	}
	if v := q.Get("offset"); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n >= 0 {
			offset = n
		}
	}
	if limit > 100 {
		limit = 100
	}
	return limit, offset
}

func paginate(books []*Book, limit, offset int) []*Book {
	if offset >= len(books) {
		return []*Book{}
	}
	end := offset + limit
	if end > len(books) {
		end = len(books)
	}
	return books[offset:end]
}

func main() {
	books := []*Book{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}

	q, _ := url.ParseQuery("limit=2&offset=2")
	limit, offset := parsePagination(q)
	page := paginate(books, limit, offset)
	for _, b := range page {
		fmt.Println(b.ID)
	}
}

parsePagination — HAR DOIM OQILONA STANDART qiymat bilan boshlanadi (limit=10, offset=0), va faqat TO'G'RI (musbat/manfiy bo'lmagan) qiymat kelsagina UNI qo'llaydi — noto'g'ri yoki bo'sh parametr dastur QULASHIGA emas, STANDART qiymatga olib keladi. if limit > 100 { limit = 100 } — mijoz limit=1000000 deb so'rasa ham, server O'ZINI himoya qiladi: bitta so'rov BUTUN bazani qaytarib yubormaydi.

paginate — Go slice'ining [offset:end] KESISH (slicing) amalidan foydalanadi ("Slices" darsini eslang): offset — qayerdan BOSHLASH, end — qayerda TO'XTASH. offset >= len(books) tekshiruvi — mijoz OXIRGI sahifadan HAM UZOQROQQA so'rov yuborsa (masalan offset=1000, atigi 5 ta yozuv bo'lsa), dastur QULAMASLIGINI ("index out of range" xatosisiz) ta'minlaydi.

>_ Exercise

Sahifalashni HAQIQIY HTTP endpoint'ga ulang va chegara holatlarini sinang.

  • "GET /books" handlerini yozing: r.URL.Query() orqali parsePagination va paginate'ni chaqirib, natijani JSON massiv qilib qaytaring
  • 150 ta kitobdan iborat ro'yxat yarating (strconv.Itoa(i) bilan ID'lar 1 dan 150 gacha)
  • "?limit=500" so'rovi yuboring — natija 100 tadan OSHMASLIGI kerak (chegaraga tortilgan)
  • "?offset=1000" so'rovi yuboring — natija BO'SH (0 ta) bo'lishi kerak
  • har ikki holatning natija UZUNLIGINI chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Limit/offset sahifalash — katta ro'yxatni BOSHQARILADIGAN qismlarga bo'ladi; server HAR DOIM limitga YUQORI CHEGARA qo'yishi va offset ro'yxat uzunligidan OSHIB ketgan holatni HISOBGA olishi kerak.

NEXT UP

Pagination: Cursor-Based