Menggunakan API Graf

Kami membahas dasar-dasar terminologi dan struktur API Graf di sinopsis API Graf. Dokumen ini membahas tentang beragam operasi yang dapat Anda lakukan dengan API Graf dengan lebih detail.

HTTP/1.1

Semua transfer data sesuai dengan HTTP/1.1, dan semua endpoint memerlukan HTTPS. Kami juga telah mengaktifkan HSTS includeSubdomains secara langsung di facebook.com, namun ini tidak akan mempengaruhi panggilan API Graf Anda.

URL Host

Hampir semua permintaan diteruskan ke URL host graph.facebook.com. Satu-satunya pengecualian adalah unggahan video, yang alih-alih menggunakan graph-video.facebook.com.

Token Akses

Dengan token akses, aplikasi Anda dapat mengakses API Graf. Pada umumnya token akses memiliki dua fungsi:

  • membuat aplikasi Anda dapat mengakses informasi Pengguna tanpa memerlukan kata sandi Pengguna, dan
  • membuat kami dapat mengenali aplikasi Anda, Pengguna yang menggunakan aplikasi Anda, dan jenis data yang aksesnya untuk aplikasi Anda telah diizinkan oleh Pengguna.

Semua endpoint API Graf memerlukan token akses, maka setiap kali Anda mengakses sebuah endpoint, Anda harus menyertakan token akses di permintaan Anda.

Cara Kerja Token

Token akses sesuai dengan protokol OAuth 2.0. OAuth 2.0 membuat entitas seperti Pengguna atau Halaman dapat mengotorisasi token. Biasanya ini dilakukan melalui antarmuka web. Setelah diberi otorisasi, aplikasi dapat menggunakan token tersebut untuk mengakses informasi tertentu.

Sebagai contohnya, aplikasi ini meminta izin dari Pengguna untuk mengakses foto, video, dan alamat email Pengguna:

Seperti yang Anda lihat, ini adalah antarmuka Facebook. Pengguna baru saja menggunakan antarmuka untuk login ke akunnya, sehingga membuat kami dapat mengautentikasi Pengguna tersebut. Jika Pengguna melanjutkan, maka kami akan menukarkan token yang lama (token Aplikasi) dengan token yang baru (token Pengguna). Aplikasi kemudian dapat menggunakan token Pengguna yang baru untuk membuat permintaan API Graf yang hanya dapat mengakses foto, video, dan alamat email Pengguna tersebut.

Ini adalah atribut token akses yang penting. ID aplikasi dan Pengguna sama-sama dikodekan dalam token itu sendiri (di antara hal lainnya), dan kami menggunakan ID tersebut untuk melacak data mana yang diizinkan Pengguna diakses oleh aplikasi. Misalkan jika Anda memeriksa token setelah Pengguna memberikan izin, maka informasi berikut akan terlihat:

Karena token mengizinkan akses ke data Pengguna, dan karena token dapat digunakan oleh semua orang, token memiliki nilai yang sangat tinggi. Oleh karena itu, berhati-hatilah saat menggunakannya dalam kueri Anda. Cara termudah untuk melakukannya adalah dengan menggunakan Facebook Login untuk menangani token Anda.

Facebook Login

OAuth 2.0 melibatkan begitu banyak pengalihan, permintaan login, dan pertukaran token, jadi demi mempermudah Anda, kami membuat produk bernama Facebook Login. Facebook Login memiliki fungsi dan metode yang mudah digunakan untuk semua SDK kami, sehingga dapat mempermudah pemanfaatan token akses ketimbang membangun solusi Anda sendiri.

Untuk membaca selengkapnya tentang token akses dan Facebook Login, atau untuk mempelajari cara membangun solusi Anda sendiri, bukalah dokumentasi Facebook Login kami.

Pembacaan

Node

Operasi pembacaan hampir selalu diawali dengan node. Node adalah suatu objek yang memiliki ID unik. Ada begitu banyak objek node Halaman yang masing-masing memiliki ID uniknya. Sebagai contohnya, Halaman Coca-Cola adalah satu-satunya yang memiliki ID 820882001277849. Untuk membaca node, kuerilah ID objek tertentu. Jadi, untuk dapat membaca node Halaman Coca-Cola, Anda akan mengkueri ID-nya:

GET https://graph.facebook.com/820882001277849

Permintaan ini secara default akan menghasilkan kolom berikut (properti node) yang diformat dengan menggunakan JSON:

{
  "name": "Coca-Cola",
  "id": "820882001277849"
}

Edge

Node memiliki edge yang biasanya dapat menghasilkan koleksi node-node lainnya yang terikat dengan edge tersebut. Untuk membaca sebuah edge, Anda harus menyertakan ID node dan nama edge di path. Seperti misalnya, node /page memiliki edge /feed yang dapat menghasilkan semua node Postingan pada Halaman. Berikut adalah cara Anda dapat menggunakan edge untuk memperoleh semua Postingan di Halaman Coca-Cola:

GET https://graph.facebook.com/820882001277849/feed

Tanggapan JSON akan terlihat seperti ini:

{
  "data": [
    {
      "created_time": "2017-12-08T01:08:57+0000",
      "message": "Love this puzzle. One of my four coke puzzles",
      "id": "820882001277849_1805191182846921"
    },
    {
      "created_time": "2017-12-07T20:06:14+0000",
      "message": "You need to add grape as a flavor for Coke in your freestyle machines.",
      "id": "820882001277849_1804966026202770"
    },
    {
      "created_time": "2017-12-07T01:29:12+0000",
      "message": "Plz play the old commercial’s with the polar bears. Would be nice to see them this holiday",
      "id": "820882001277849_1804168469615859"
    }
  ]
}

Perhatikan bahwa tanggapan tersebut tidak hanya memuat ID node Postingan di dalam koleksi, namun juga kolom created_time dan message juga. Ini wajar. Sebagian besar edge akan menyertakan satu atau beberapa kolom secara default.

Kolom

Kolom adalah properti node. Saat Anda mengkueri sebuah node, maka kueri tersebut akan menghasilkan sebuah set kolom secara default, sebagaimana contoh yang ditampilkan di atas. Namun, Anda dapat menentukan kolom apa yang ingin Anda hasilkan dengan menggunakan parameter fields dan mencantumkan setiap kolom. Ini akan menimpa hasil default dan hanya menghasilkan kolom yang Anda tentukan, beserta ID objek yang selalu dihasilkan.

Misalnya, referensi node Halaman menandakan kolom apa yang Anda minta ketika membaca node Halaman. Jika Anda ingin memperoleh kolom about, fan_count, dan website untuk Halaman Coca-Cola, Anda dapat melakukan ini:

GET https://graph.facebook.com/820882001277849
    ?fields=about,fan_count,website

Ini akan menghasilkan tanggapan berikut:

{
  "about": "Welcome to the happiest Facebook page on, um, Facebook.",
  "fan_count": 106714402,
  "website": "http://coca-cola.com",
  "id": "820882001277849"
}

Edge, yang biasanya menghasilkan koleksi objek, juga menghasilkan kolom tentang masing-masing objek yang ada di dalam koleksi. Misalkan saja Anda menggunakan edge /photos untuk memperoleh semua node Foto di Halaman Coca-Cola:

GET https://graph.facebook.com/820882001277849/photos

Ini akan membuat tanggapan yang terlihat seperti ini:

{
  "data": [
    {
      "created_time": "2016-08-23T13:12:10+0000",
      "id": "1308573619175349"
    },
    {
      "created_time": "2016-08-05T22:34:19+0000",
      "id": "1294456907253687"
    },
    {
      "created_time": "2016-04-29T16:17:02+0000",
      "id": "1228552183844160"
    }
  ]
}

Sebagaimana yang Anda lihat, edge /photos secara default akan menghasilkan koleksi ID node Foto beserta properti created_time untuk masing-masing foto. Seperti halnya dengan node, Anda dapat menggunakan parameter fields untuk menentukan kolom apa yang Anda inginkan untuk setiap objek yang dihasilkan di dalam koleksi.

Misalnya Anda ingin mendapatkan kolom height, width, dan link (URL) untuk setiap node Foto yang dihasilkan oleh edge /photos:

GET https://graph.facebook.com/820882001277849/photos
      ?fields=height,width,link

Seperti inilah penampilan tanggapannya:

{
  "data": [
    {
      "height": 720,
      "width": 720,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1308573619175349/?type=3",
      "id": "1308573619175349"
    },
    {
      "height": 720,
      "width": 720,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1294456907253687/?type=3",
      "id": "1294456907253687"
    },
    {
      "height": 180,
      "width": 180,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1228552183844160/?type=3",
      "id": "1228552183844160"
    }
  ]
}

Perhatikan bahwa Anda dapat menentukan edge dengan parameter fields juga, yang berguna ketika Anda menggunakan ekspansi kolom.

Perluasan Kolom

Jika Anda menguji kueri GET /page/photos di atas di dalam Penjelajah API Graf, Anda mungkin akan melihat bahwa permintaan menghasilkan lebih dari tiga objek dan hasil yang dipaginasikan. Ini umum bagi sebagian besar edge. Kami akan membahas penelusuran hasil dalam waktu dekat, namun untuk saat ini, mari kita lihat ekspansi kolom yang membuat Anda tidak hanya dapat melakukan kueri nested, namun juga membatasi dan memesan hasilnya.

Pembatasan Hasil

Pembatasan membuat Anda dapat mengontrol jumlah objek yang dihasilkan dalam setiap set hasil yang dipaginasikan. Untuk membatasi hasil, tambahkan argumen .limit() ke kolom atau edge.

Misalnya, dengan melakukan permintaan GET di edge /feed Halaman Coca-Cola, hal tersebut dapat menghasilkan ratusan Postingan. Anda dapat membatasi jumlah Postingan yang dihasilkan untuk setiap halaman hasil dengan melakukan hal berikut:

GET https://graph.facebook.com/820882001277849
    ?fields=feed.limit(3)

Ini akan menghasilkan semua Postingan di Halaman Coca-Cola, namun membatasi jumlah objek di setiap halaman hasil menjadi tiga. Perhatikan bahwa alih-alih menentukan edge Kabar Beranda di URL path (/page/feed), Anda menentukannya di parameter fields (?fields=feed), sehingga membuat Anda dapat melampirkan argumen .limit(3).

Berikut adalah hasil kueri:

{
  "feed": {
    "data": [
      {
        "created_time": "2017-12-12T01:24:21+0000",
        "message": "This picture of my grandson with Santa screams Coca Cola",
        "id": "820882001277849_1809387339093972"
      },
      {
        "created_time": "2017-12-11T23:40:17+0000",
        "message": ":)",
        "id": "820882001277849_1809316002434439"
      },
      {
        "created_time": "2017-12-11T23:31:38+0000",
        "message": "Thought you might enjoy this.  My horse loves Coke!",
        "id": "820882001277849_1809310929101613"
      }
    ],
    "paging": {
      "cursors": {
        "before": "Q2c4U1pXNTBYM0YxWlhKNVgzTjBiM0o1WDJsa0R5UTRNakE0T0RJd01ERXlOemM0TkRrNkxUVXdPRE16TXpVM01EQXpNVFUwTkRRME5Ua1BER0ZA3YVY5emRHOXllVjlwWkE4ZA09ESXdPRGd5TURBeE1qYzNPRFE1WHpFNE1Ea3pPRGN6TXprd09UTTVOeklQQkhScGJXVUdXaTh2eFFFPQZDZD",
        "after": "Q2c4U1pXNTBYM0YxWlhKNVgzTjBiM0o1WDJsa0R5TTRNakE0T0RJd01ERXlOemM0TkRrNk1UTTJORE01T0RVNU1UZAzVPRGMyTnpFNE1BOE1ZAWEJwWDNOMGIzSjVYMmxrRHlBNE1qQTRPREl3TURFeU56YzRORGxmTVRnd09USXdOamsxTlRjM09EWTNOdzhFZAEdsdFpRWmFMdk9HQVE9PQZDZD"
      },
      "next": "https://graph.facebook.com/820882001277849/feed?access_token=valid_token_goes_here"
    }
  },
  "id": "820882001277849"
}

Sebagaimana yang Anda lihat, hanya tiga objek yang muncul di halaman yang memuat paginasi hasil ini, namun tanggapannya menyertakan kolom dan URL next yang dapat Anda gunakan untuk mengambil halaman selanjutnya.

Pemesanan Hasil

Anda dapat memesan hasil berdasarkan waktu pembuatan objek. Untuk melakukan ini, gunakan argumen .order() dengan salah satu nilai berikut di kolom maupun di edge.

  • chronological — memesan hasil dengan objek yang dibuat paling awal terlebih dahulu.
  • reverse_chronological — memesan hasil dengan objek yang dibuat paling akhir terlebih dahulu.

Untuk contohnya, mari kita dapatkan semua Komentar di salah satu Postingan video Halaman Coca-Cola (1809938745705498), pesan hasil dalam urutan kronologis (usia terlama terlebih dahulu), dan batasi jumlah objek per hasil yang dipaginasikan menjadi tiga:

GET https://graph.facebook.com/1809938745705498
    ?fields=comments.order(chronological).limit(3)

Sekali lagi, perhatikan bahwa agar dapat menggunakan argumen di sebuah edge, Anda harus menentukan edge-nya di parameter fields. Sebagaimana yang Anda lihat, Anda dapat memadukan argumen .limit() dan .order() di kolom atau edge tunggal.

Berikut adalah hasilnya:

{
  "comments": {
    "data": [
      {
        "created_time": "2017-12-12T14:12:20+0000",
        "message": ":) :) :)",
        "id": "1809938745705498_1809939942372045"
      },
      {
        "created_time": "2017-12-12T14:14:03+0000",
        "message": "seasons greetings!",
        "id": "1809938745705498_1809941802371859"
      },
      {
        "created_time": "2017-12-12T14:14:11+0000",
        "message": "My bestie <3",
        "id": "1809938745705498_1809941879038518"
      }
    ],
    "paging": {
      "cursors": {
        "before": "WTI5dGJXVnVkRjlqZAFhKemIzSTZANVGd3T1Rrek9UZAzROVGN3TlRNNE5Eb3hOVEV6TURnM09UTTIZD",
        "after": "WTI5dGJXVnVkRjlqZAFhKemIzSTZANVGd4TURBd09UazROVFk1T0RNM05Eb3hOVEV6TURreU5qQXoZD"
      },
      "next": "https://graph.facebook.com/1809938745705498/comments?access_token=valid_token_goes_here"
    }
  },
  "id": "1809938745705498"
}

Penerbitan

Sebagian besar edge membuat Anda dapat menerbitkan objek ke koleksi di sebuah node. Anda dapat melakukan ini dengan menggunakan permintaan POST di edge node. Sebagai contohnya, Anda dapat menerbitkan Komentar di sebuah Foto dengan menggunakan edge /comments node Foto:

POST https://graph.facebook.com
  /1809938745705498
    /comments
      ?message=Awesome!

Jika berhasil, maka sebagian besar edge akan menghasilkan ID objek yang baru saja Anda terbitkan, yang sering kali berupa kombinasi ID objek yang diterbitkan dan string ID baru:

{
  "id": "1809938745705498_1810399758992730"
}

Penerbitan biasanya memerlukan izin tambahan, jadi bukalah dokumentasi referensi untuk masing-masing edge guna dapat menentukan izin apa yang diperlukan.

Token akses yang digunakan untuk menerbitkan objek dapat memengaruhi penampilan objek. Jika token akses Halaman digunakan, objek akan muncul seolah-olah Halaman memposting objeknya. Di samping itu, token akses Pengguna akan menyebabkan objeknya muncul seolah-olah seseorang mempostingnya.

Banyak edge juga mendukung fitur lanjutan seperti Read-After-Write yang membuat Anda dapat membaca objek yang baru saja diterbitkan, dan Penerbitan Batch yang membuat Anda dapat melakukan sejumlah operasi penerbitan berantai sekaligus.

Mengupdate

Anda dapat melakukan operasi update pada node yang sudah ada dengan menggunakan permintaan POST. Misalnya, untuk mengupdate kolom message di Komentar yang sudah ada, Anda dapat melakukan hal ini:

POST https://graph.facebook.com
  /1809938745705498_1810399758992730
    ?message=Happy%20Holidays!

Jika berhasil, node akan menghasilkan kolom success dan nilai true:

{
  "success": true
}

Sebagaimana operasi penerbitan, operasi update memerlukan izin tambahan yang akan tercantum di dokumentasi referensi masing-masing node. Dan sebagaimana sebagian besar edge, banyak node mendukung Read-After-Write.

Menghapus

Anda biasanya dapat menghapus node dengan menggunakan operasi DELETE:

DELETE https://graph.facebook.com
  /1809938745705498_1810399758992730

Jika berhasil, node akan menghasilkan kolom success dan nilai true:

{
  "success": true
}

Biasanya Anda hanya dapat menghapus node yang Anda buat, namun periksalah panduan referensi masing-masing node untuk melihat persyaratan operasi penghapusannya.

Guna mendukung klien yang tidak mendukung semua metode HTTP, Anda dapat mengirimkan permintaan POST ke node dan menyertakan parameter dan nilai method=delete untuk menimpa metode HTTP:

POST https://graph.facebook.com
  /1809938745705498_1810399758992730
    ?method=delete

Melintasi Hasil Berhalaman

Saat Anda membuat permintaan API ke node atau edge, biasanya Anda tidak selalu menerima semua hasil permintaan itu dalam satu tanggapan. Ini karena beberapa tanggapan dapat berisi ribuan objek sehingga sebagian besar tanggapan dipaginasikan secara default.

Paginasi Berbasis Kursor

Paginasi berbasis kursor merupakan metode pembuatan halaman paling efisien dan harus selalu digunakan jika memungkinkan. Kursor merujuk pada string karakter acak yang menandai item tertentu dalam daftar data. Kecuali item ini dihapus, kursor selalu mengarah pada bagian daftar yang sama, namun ini akan tidak berlaku lagi jika item dihapus. Oleh karena itu, aplikasi Anda seharusnya tidak menyimpan kursor dan berasumsi bahwa kursor tersebut masih akan valid di waktu mendatang.

Ketika membaca edge yang mendukung paginasi kursor, Anda akan melihat tanggapan JSON berikut:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "cursors": {
      "after": "MTAxNTExOTQ1MjAwNzI5NDE=",
      "before": "NDMyNzQyODI3OTQw"
    },
    "previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
    "next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
  }
}

Edge dengan paginasi kursor mendukung parameter berikut:

  • before : Ini adalah kursor yang mengarah pada bagian mulai halaman data yang sudah dikembalikan.
  • after : Ini adalah kursor yang mengarah pada bagian akhir halaman data yang telah dikembalikan.
  • limit : Ini adalah jumlah objek maksimal yang dapat dikembalikan. Sebuah pencarian dapat mengembalikan lebih sedikit dari nilai limit karena pemfilteran. Jangan bergantung pada jumlah hasil yang lebih sedikit dari nilai limit untuk mengindikasikan bahwa pencarian Anda mencapai akhir daftar data, gunakan ketiadaan next seperti yang dijelaskan di bawah. Misalnya, jika Anda menetapkan limit ke 10 dan 9 hasil dikembalikan, mungkin ada lebih banyak data yang tersedia, tetapi satu item dihapus karena pemfilteran privasi. Beberapa edge juga memiliki nilai maksimal atas limit karena alasan kinerja. Dalam semua kejadian, API mengembalikan tautan paginasi halaman yang tepat.
  • next : Endpoint API Graf yang akan mengembalikan halaman berikutnya dari data tersebut. Jika tidak disertakan, berarti menjadi halaman yang terakhir dari data tersebut. Karena paginasi berfungsi dengan visibilitas dan privasi, maka dimungkinkan bahwa halaman dapat kosong namun berisi tautan paging 'berikutnya'. Hentikan paging saat tautan 'selanjutnya' tidak muncul lagi.
  • previous : Endpoint API Graf yang akan mengembalikan halaman sebelumnya dari data tersebut. Jika tidak disertakan, berarti menjadi halaman yang pertama dari data tersebut.

Jangan menyimpan kursor. Kursor dapat seketika tidak valid jika item ditambahkan atau dihapus.

Paginasi Berbasis Waktu

Paginasi waktu digunakan untuk menelusuri data hasil menggunakan cap waktu Unix yang menunjuk pada waktu tertentu di daftar data.

Apabila menggunakan endpoint yang menggunakan paginasi berbasis waktu, Anda akan melihat tanggapan JSON berikut:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "previous": "https://graph.facebook.com/me/feed?limit=25&since=1364849754",
    "next": "https://graph.facebook.com/me/feed?limit=25&until=1364587774"
  }
}

Edge dengan paginasi waktu mendukung parameter berikut:

  • until : Cap waktu Unix atau nilai data strtotime yang mengarah pada bagian akhir rentang data berbasis waktu.
  • since : Cap waktu Unix atau nilai data strtotime yang mengarah pada bagian mulai rentang data berbasis waktu.
  • limit : Ini adalah jumlah objek maksimal yang dapat dikembalikan. Sebuah pencarian dapat mengembalikan lebih sedikit dari nilai limit karena pemfilteran. Jangan bergantung pada jumlah hasil yang lebih sedikit dari nilai limit untuk mengindikasikan bahwa pencarian Anda mencapai akhir daftar data, gunakan ketiadaan next seperti yang dijelaskan di bawah. Misalnya, jika Anda menetapkan limit ke 10 dan 9 hasil dikembalikan, mungkin ada lebih banyak data yang tersedia, tetapi satu item dihapus karena pemfilteran privasi. Beberapa edge juga memiliki nilai maksimal atas limit karena alasan kinerja. Dalam semua kejadian, API mengembalikan tautan paginasi halaman yang tepat.
  • next : Endpoint API Graf yang akan mengembalikan halaman berikutnya dari data tersebut.
  • previous : Endpoint API Graf yang akan mengembalikan halaman sebelumnya dari data tersebut.

Untuk hasil yang konsisten, tentukan parameter since dan until. Juga disarankan agar perbedaan waktu maksimalnya adalah 6 bulan.

Paginasi Berbasis Offset

Paginasi offset dapat digunakan apabila Anda tidak begitu mementingkan linimasa dan hanya ingin nomor objek tertentu yang dikembalikan. Paginasi ini hanya dapat digunakan jika edge tidak mendukung paginasi berbasis kursor atau halaman.

Edge dengan paginasi offset mendukung parameter berikut:

  • offset : Ini akan menentukan offset titik mulai setiap halaman berdasarkan nomor yang ditentukan.
  • limit : Ini adalah jumlah objek maksimal yang dapat dikembalikan. Sebuah pencarian dapat mengembalikan lebih sedikit dari nilai limit karena pemfilteran. Jangan bergantung pada jumlah hasil yang lebih sedikit dari nilai limit untuk mengindikasikan bahwa pencarian Anda mencapai akhir daftar data, gunakan ketiadaan next seperti yang dijelaskan di bawah. Misalnya, jika Anda menetapkan limit ke 10 dan 9 hasil dikembalikan, mungkin ada lebih banyak data yang tersedia, tetapi satu item dihapus karena pemfilteran privasi. Beberapa edge juga memiliki nilai maksimal atas limit karena alasan kinerja. Dalam semua kejadian, API mengembalikan tautan paginasi halaman yang tepat.
  • next : Endpoint API Graf yang akan mengembalikan halaman berikutnya dari data tersebut. Jika tidak disertakan, berarti menjadi halaman yang terakhir dari data tersebut. Karena paginasi berfungsi dengan visibilitas dan privasi, maka dimungkinkan bahwa halaman dapat kosong namun berisi tautan paging 'berikutnya'. Hentikan paging saat tautan 'selanjutnya' tidak muncul lagi.
  • previous : Endpoint API Graf yang akan mengembalikan halaman sebelumnya dari data tersebut. Jika tidak disertakan, berarti menjadi halaman yang pertama dari data tersebut.

Perhatikan bahwa jika objek baru ditambahkan ke daftar item yang sedang ditentukan halaman, maka konten dari masing-masing halaman berbasis offset akan berubah.

Penomoran halaman berbasis offset tidak didukung untuk semua panggilan API. Untuk mendapatkan hasil yang konsisten, kami menyarankan Anda untuk melakukan paginasi menggunakan tautan sebelumnya/berikutnya yang kami kembalikan dalam tanggapan.