YouTube2Text

API Pagination - Offset and Cursor Pagination Explained - Backend Engineering — Transcript

by Caleb Curry · 4,182 words · 597 segments · language en · Watch on YouTube

Full transcript

  1. 0:00Hey, what's going on? In this lesson,
  2. 0:01we're going to talk about pageionation
  3. 0:02for APIs. We're going to talk about a
  4. 0:04couple of different approaches, why you
  5. 0:06might want to page your data at all, and
  6. 0:09then what it's going to look like from
  7. 0:11the client's perspective, the different
  8. 0:13approaches to consuming a pageionated
  9. 0:15API. Now, before we get started, I want
  10. 0:17to mention I have a link to the notes,
  11. 0:19which will have all the information we
  12. 0:20talk about here with references,
  13. 0:22resources, as well as examples. So, you
  14. 0:25should definitely check that out. We'll
  15. 0:26have a link down below. This is also
  16. 0:28part of a larger API and backend
  17. 0:29playlist. So I'll have a link for that
  18. 0:31playlist too. So first off, what is
  19. 0:32pageionation
  20. 0:37and why would you want to do it? So
  21. 0:40let's say we have 10,000 elements
  22. 0:44and let's say we want to retrieve this
  23. 0:47data from an API. The default behavior
  24. 0:50may be to select all 10,000 of those
  25. 0:52elements and send that to the user.
  26. 0:54Well, what this is going to do is one,
  27. 0:57put a lot of effort on the database to
  28. 1:00retrieve all of that data, and two, when
  29. 1:02we send that over the line to the
  30. 1:04client,
  31. 1:07we have to send a lot of data.
  32. 1:13This is ultimately going to slow down
  33. 1:14the response from the API because the
  34. 1:17amount of data is so large. So, what we
  35. 1:19could do instead is we could split this
  36. 1:21up into pages. Let's say groups of 100.
  37. 1:24We send that to the client and most of
  38. 1:26the time that's going to be enough as
  39. 1:29the times you go from page one to page
  40. 1:32two to page three
  41. 1:35is quite small actually. So most of the
  42. 1:40visits will be on these first pages.
  43. 1:43I mean just think about it with a Google
  44. 1:45search. How often do you go to page two
  45. 1:47of Google?
  46. 1:51you know, maybe that's 10% of the time
  47. 1:53or something like that. And then from
  48. 1:54there, 10% of the time, you'll go to
  49. 1:56page three. So almost all of that data
  50. 1:58is not even going to be needed. Now, you
  51. 2:00have to think about how the client might
  52. 2:02use this pageionated API because if they
  53. 2:05do need all of this data for some
  54. 2:07reason, now they're going to have to
  55. 2:08make tons of requests grabbing the data
  56. 2:11100 at a time. So, we also don't want to
  57. 2:13up the request count too much.
  58. 2:17So, that's one of the potential
  59. 2:18tradeoffs. If you reduce the page size,
  60. 2:21you're going to get more requests to the
  61. 2:23server for more data. So you have to
  62. 2:25think of the ideal page size.
  63. 2:28How many elements do you want to return?
  64. 2:30And is this something that you can
  65. 2:32configure from the client?
  66. 2:35Those are things you need to consider
  67. 2:38when you're designing your API. And this
  68. 2:40might be something that's not universal
  69. 2:42across all of your different resources
  70. 2:44in your API. There might be certain ones
  71. 2:46where you adjust the default page size
  72. 2:50for that use case. If in many scenarios
  73. 2:53the user is going to work through a lot
  74. 2:55of this data, you can just create a
  75. 2:56custom endpoint
  76. 2:59appropriate for whatever the use case
  77. 3:02is.
  78. 3:04I mean, you could think of an example
  79. 3:05like this where we might have some
  80. 3:07campaigns or something and you could
  81. 3:09page it or you could just have a custom
  82. 3:10endpoint like slashall. If you know you
  83. 3:13have a web page where you need to
  84. 3:15display all of those values, that might
  85. 3:17be okay for some things, but for others,
  86. 3:20it's just not going to work. I mean,
  87. 3:22think of like YouTube. They couldn't
  88. 3:24just grab all of the comments in a
  89. 3:26single query. So most of the time we're
  90. 3:28going to concern oursel with paging and
  91. 3:31then the appropriate page size for the
  92. 3:33client. So we're going to talk about
  93. 3:35some of those things now. So first let's
  94. 3:37talk about the API structure for a
  95. 3:39pageionated API endpoint. And this is
  96. 3:42one of the reasons I recommended nesting
  97. 3:44your data in some attribute. Let's just
  98. 3:47say that attribute is data.
  99. 3:50And then we have our data here inside of
  100. 3:54an array. And having it in this kind of
  101. 3:57structure allows us to easily add in
  102. 3:59other attributes here that can be used
  103. 4:01for paging through the data. So then the
  104. 4:03client knows if they want to access the
  105. 4:05data, they just go into the data
  106. 4:07attribute. If they want to access paging
  107. 4:10data, they can grab whatever else such
  108. 4:12as
  109. 4:14next. So what kind of attributes would
  110. 4:16we put in here? This is going to depend
  111. 4:18on your approach to pageionation. We're
  112. 4:20going to talk about a couple of
  113. 4:21different approaches, but just to get us
  114. 4:23started, I'll show you an example.
  115. 4:25We may have something like the count
  116. 4:28which is the total number of elements.
  117. 4:33We may have for ease to the client a
  118. 4:38next attribute which could be a URL to
  119. 4:42the next page and then a similar thing
  120. 4:44for the previous page. So the consumer
  121. 4:48of this API
  122. 4:54can navigate very easily just grabbing
  123. 4:57those attributes. But we can customize
  124. 5:00this behavior. We can do whatever
  125. 5:01structure we want as long as the client
  126. 5:04knows how to take this information and
  127. 5:06go to the next page. So let's now talk
  128. 5:09about the types of pageionation.
  129. 5:15And now we're going to cover two main
  130. 5:17classifications with the first
  131. 5:19classification having kind of two
  132. 5:21different approaches. So we will talk
  133. 5:24about offset based
  134. 5:31and we will talk about cursorbased.
  135. 5:36These are two different approaches with
  136. 5:38different pros and cons. Sometimes
  137. 5:40you'll have a business decision that
  138. 5:41will force a certain one of these. Other
  139. 5:44times you can choose between the two. So
  140. 5:46we'll talk about when you have to use a
  141. 5:49certain one of these. So first let's
  142. 5:50talk about offsetbased pageionation.
  143. 5:53This will use a page attribute or it
  144. 5:57will use an offset and a limit.
  145. 6:03These are basically two different
  146. 6:05approaches or two ways of describing the
  147. 6:07same capability. So we're going to first
  148. 6:10take a look at just working with a page
  149. 6:12number. Then we'll talk about how to
  150. 6:14customize it a bit with an offset and a
  151. 6:16limit. After we go over offset based, we
  152. 6:18will then circle back and look at
  153. 6:20cursorbased pageionation. So let's say
  154. 6:22we have an endpoint slash comments
  155. 6:25and then you use a URL parameter
  156. 6:29such as page and then specify a value
  157. 6:32such as three. This request will be sent
  158. 6:34to our backend and the backend is going
  159. 6:37to have some attribute page size.
  160. 6:42Let's just say it's a default of 20.
  161. 6:45Now, how you split up the data is
  162. 6:47totally up to you in this situation. I'm
  163. 6:49going to do it by ID, but you could sort
  164. 6:52it in any way. IDs are very easy to
  165. 6:54think about cuz they're numbered, but
  166. 6:56you could sort by any column. So, let's
  167. 6:58take a look at what page one might look
  168. 7:00like. That would be IDs 1 through 20.
  169. 7:06Page two would be 21 through 40.
  170. 7:12and then page three would be 41 through
  171. 7:1660. So by specifying page three, we
  172. 7:19would retrieve this data. And then
  173. 7:22inside of our API endpoint, we would
  174. 7:23have a next attribute pointing to the
  175. 7:25next page. And it would just be the same
  176. 7:27URL but with a page equal to four. So
  177. 7:29really simple for the URL navigation. By
  178. 7:32far the easiest for the client to
  179. 7:34understand. And then a previous would
  180. 7:36just be page two. So the question then
  181. 7:37is how do we go from a number here to an
  182. 7:39actual database query?
  183. 7:42Let's write up what this query might
  184. 7:44look like. So if the page is three, we
  185. 7:47could have select
  186. 7:50everything
  187. 7:52from whatever table.
  188. 7:55Let's say comments order by
  189. 7:59ID or comment ID. And then we can pass
  190. 8:02to the database a limit.
  191. 8:05This is going to be the set page size.
  192. 8:08So 20 how many elements per page and
  193. 8:11then we will provide an offset
  194. 8:16which is how many rows to skip. So I
  195. 8:18think we mentioned page one was 1
  196. 8:21through 20 then page two was 21 through
  197. 8:2640 and then page three was 41 through
  198. 8:2960. So if we wanted to jump to page
  199. 8:32three of our data we would use an offset
  200. 8:35of 40. Now the important thing to
  201. 8:37understand here is that this is going to
  202. 8:39start with the 41st row.
  203. 8:43So this does not have knowledge of the
  204. 8:46actual ID value. This is going off of
  205. 8:49row counts. It just so happens that we
  206. 8:51have a perfectly sequential number from
  207. 8:53one all the way up through 40. So that's
  208. 8:55our first approach really is just taking
  209. 8:58a page from the client and converting it
  210. 9:00to some query. But you'll see here we
  211. 9:02have this limit and offset. We're really
  212. 9:04just translating that page number into
  213. 9:06values here. We could just expose these
  214. 9:08two things to the client and allow them
  215. 9:10to provide arbitrary values for these
  216. 9:12and that'll be very similar to the page
  217. 9:14structure. It's just a little bit more
  218. 9:16exposed to the client. Even before
  219. 9:19jumping to that approach though, you can
  220. 9:20give customization to the client. So for
  221. 9:22example, you could allow them to provide
  222. 9:26a page size as a URL parameter and then
  223. 9:29that could change the query to something
  224. 9:32else using this value for the limit
  225. 9:37and also the math to adjust the offset.
  226. 9:42So you can think of the offset
  227. 9:46as just the page minus one times the
  228. 9:51page size.
  229. 9:54So for example to get the value 40 from
  230. 9:56our previous example we had page 3. 3 -
  231. 9:591 is 2 and then 2 * the page size. By
  232. 10:04default it was 20. So that gives us 40.
  233. 10:08So it's a really simple operation to go
  234. 10:10from a page number to the appropriate
  235. 10:13offset. So if we wanted to allow these
  236. 10:15to be provided from the user, we might
  237. 10:17get something like slash comments
  238. 10:22and then a query parameter limit being
  239. 10:26equal to say 30 and an offset of
  240. 10:32120. And now we don't have specific page
  241. 10:35numbers. Instead, we just have these
  242. 10:36values which are then translated to
  243. 10:39grabbing a certain number of rows from
  244. 10:40the database. And this is really simple.
  245. 10:42We just pass this directly to the
  246. 10:45database. Limit 30
  247. 10:50offset
  248. 10:52120. Now, be sure to do any kind of
  249. 10:55parameterization or filtering so we
  250. 10:57don't get any SQL injection attacks. But
  251. 11:00that's basically what we're doing. We
  252. 11:01just substitute those values in
  253. 11:03directly. then the database just grabs
  254. 11:05the appropriate rows. So the page ID and
  255. 11:08the limit and the offset ID are the same
  256. 11:11thing behind the scenes. It's just
  257. 11:13changing how the user interacts with the
  258. 11:16API. The next attribute
  259. 11:19would look something like this. Comments
  260. 11:24limit 30
  261. 11:26and
  262. 11:30offset 150.
  263. 11:33So basically just adding the limit to
  264. 11:36that previous offset to get the next URL
  265. 11:39and then the client can easily click
  266. 11:41this if they're within an API viewer or
  267. 11:44just grab that in code and navigate to
  268. 11:47that path to get the next page of data.
  269. 11:49Same idea with the previous you would
  270. 11:51just subtract instead of add. So I kind
  271. 11:53of like this approach because it gives
  272. 11:54control to the client
  273. 11:57but you can still set boundaries on the
  274. 11:59back end. So you could say there's a max
  275. 12:02limit so they don't just grab all of the
  276. 12:04data. So if you went in here and put
  277. 12:063,000, maybe it would default to, you
  278. 12:08know, a max of 150 or something. But it
  279. 12:11does give the client more control and
  280. 12:12you can have a drop down that says
  281. 12:15elements per page
  282. 12:18and maybe have 20, 50, 100 so that they
  283. 12:24can choose the appropriate one for
  284. 12:25whatever they're trying to do. So what
  285. 12:27are some of the big downsides of this?
  286. 12:29Well, the big one is that this offset
  287. 12:34is rowbased. It has no concept of the
  288. 12:37data or which element it is at. It's
  289. 12:40just a number that represents how far
  290. 12:42off we are from the start of that data
  291. 12:45set. So I should say something like row
  292. 12:47number based. What this means is if the
  293. 12:50data changes as you are navigating
  294. 12:53through the pages, you could get gaps or
  295. 12:56repeating values that show up. Let's
  296. 12:58just show a very simple example of this.
  297. 13:04So here we have 10 elements and let's
  298. 13:07say we're getting three at a time. So
  299. 13:08we're looking at these three. The offset
  300. 13:11here is three. And now let's say we want
  301. 13:12to go to the next page but some data was
  302. 13:14deleted. So let's say we have 1 2 5
  303. 13:206 7 8 9 and 10. We go from an offset of
  304. 13:24three to an offset of six to go to the
  305. 13:26next page. So 1 2 3 4 five six and we
  306. 13:31start here and we go all the way to the
  307. 13:34end because we're out of data or you
  308. 13:35could think of this as grabbing 11 as
  309. 13:37well. So we basically just skipped over
  310. 13:40seven and 8 because we're using an
  311. 13:42offset. So basically anytime we add or
  312. 13:45remove data earlier on in our data set
  313. 13:48that's going to shift where we start.
  314. 13:50And if we're having that happen as we're
  315. 13:52navigating through the pages that's a
  316. 13:54pretty disruptive experience for the
  317. 13:55user. So now I want to talk about
  318. 13:57cursorbased
  319. 13:59and you can think of this as using a
  320. 14:01cursor or pointer to the last record
  321. 14:04scene and this will pretty much ignore
  322. 14:07any deletes or new data because it
  323. 14:10doesn't use an offset. You can think of
  324. 14:13it as just identifying a specific row
  325. 14:16and then going from there. So going back
  326. 14:18to that previous example. So let's say
  327. 14:20the first page had 1 2 3 and then we go
  328. 14:22to the next page and we grab four five
  329. 14:25and six
  330. 14:27and then some data is deleted. So it
  331. 14:29goes 1 2 5 6 7 8 9 and 10. Well the
  332. 14:35cursor is basically going to say hey
  333. 14:37this was our last scene.
  334. 14:41So this is where we're going to continue
  335. 14:42from and then we'll go to seven. So
  336. 14:45we're able to grab that next set of
  337. 14:46data. So in this situation, we are
  338. 14:49immune to data being added or removed.
  339. 14:52But there are a few gotchas here that
  340. 14:54you definitely need to be aware of. I'm
  341. 14:55going to talk about some of the pros and
  342. 14:56cons and when you can and cannot use
  343. 14:58cursorbased pageionation, but first I
  344. 15:00want to show you what the actual API
  345. 15:02response might look like. So to navigate
  346. 15:04to a page, you might see something like
  347. 15:06this
  348. 15:08comments and then we'll start with this.
  349. 15:12we'll say
  350. 15:15after id and then some value
  351. 15:19and then basically the backend can use
  352. 15:22that value to know where to start and
  353. 15:24then if we had an API response with a
  354. 15:26next attribute
  355. 15:28so it might be something like comments
  356. 15:31after a ID 1 2 3 7 8 or whatever it may
  357. 15:37be so in this situation we're still
  358. 15:39using a transparent URL where the value
  359. 15:42can be seen and interpreted by the
  360. 15:44client. In other words, they know what
  361. 15:46ID we're starting at. And generally,
  362. 15:49this is considered bad practice. We
  363. 15:51don't want to expose too much here. And
  364. 15:54it's also very limiting. Uh so here's
  365. 15:57some of the reasons. Risk of bad
  366. 15:58exposure, sharing too much information
  367. 16:01about the database structure and what
  368. 16:03rows exist. Limited use. In this case,
  369. 16:05it's tied to an ID. It's also confusing
  370. 16:09for the direction because we're saying
  371. 16:11after which assumes, you know, we're
  372. 16:13only going forward.
  373. 16:15So, usually all of this stuff is just
  374. 16:18hidden from the client and instead we're
  375. 16:22given a token.
  376. 16:24This may be called a continuation token
  377. 16:26or something of that nature,
  378. 16:31which basically encodes this
  379. 16:33information. you might be able to decode
  380. 16:36it. So, it's not life or death. It's not
  381. 16:39like a secret key or something. But
  382. 16:42basically, instead of having after ID 1
  383. 16:442 3 4 5, we might have something a
  384. 16:47little bit more vague, such as
  385. 16:53continuation
  386. 16:55and then some value.
  387. 16:59And this doesn't tie us into a certain
  388. 17:02column or ordering or anything like
  389. 17:04that. We can change the behind the
  390. 17:06scenes implementation if needed, but the
  391. 17:08way to interact with the API stays the
  392. 17:10same. So it's pretty common to see
  393. 17:12continuation tokens, but the same
  394. 17:15limitations and behaviors apply. So
  395. 17:17let's talk about some of the limitations
  396. 17:19of this structure. But before we erase
  397. 17:21all of this, you can imagine this value
  398. 17:25being used in an SQL statement where
  399. 17:30ID is greater than 1 2 3 7 8. So it goes
  400. 17:36by the actual ID value and continues
  401. 17:38from there. With the continuation token,
  402. 17:40it'll be very important for you to set
  403. 17:42the next attribute. Since the client is
  404. 17:47probably not going to be able to type in
  405. 17:49arbitrary values or calculate it, it'll
  406. 17:51just provide what value to use next for
  407. 17:54the next set of data. So, it's a little
  408. 17:56bit more complicated in setup and
  409. 17:58understanding from the client, but it
  410. 17:59does have some of those benefits. When
  411. 18:01data is added or removed, you're not
  412. 18:03going to have that shift and then you
  413. 18:04see some repeating data or skip data.
  414. 18:06So, let's talk about some of the
  415. 18:07limitations, some of the reasons why you
  416. 18:09would not want to do this. So, it's
  417. 18:11going to be limited to certain columns.
  418. 18:14Basically, you can think of many of the
  419. 18:15same attributes of a good primary key.
  420. 18:18It's going to be unique.
  421. 18:20Since we need to be able to uniquely
  422. 18:22identify it, it will have to be not
  423. 18:25null,
  424. 18:26unchanging,
  425. 18:28and we will want it to be indexed
  426. 18:32to get the most performance here. So,
  427. 18:35two good examples would be an ID or a
  428. 18:38creation timestamp
  429. 18:45because this isn't going to be null.
  430. 18:47It's something you could index by. It's
  431. 18:49unique. Most likely if you're not
  432. 18:51creating multiple at the same exact
  433. 18:52time, it's unchanging and you can sort
  434. 18:55by that very easily. So it could be
  435. 18:57something like the latest comments. So
  436. 18:59this is something to keep in mind
  437. 19:00because with the previous pageionation,
  438. 19:02it's very nice to use for arbitrary
  439. 19:05filtering and querying. So, if you have
  440. 19:07a big data set, I think I used in an
  441. 19:09earlier video the example of a car
  442. 19:11database and you want to sort and filter
  443. 19:14by make, model, price, all of these
  444. 19:17different attributes, that's where a
  445. 19:19paging system could be quite nice
  446. 19:21because we're not limited to some of
  447. 19:23these things with continuation tokens.
  448. 19:26And this is a big one. Depending on if
  449. 19:28you need this or not, you're not going
  450. 19:30to be able to do arbitrary page jumps.
  451. 19:33It's pretty much just next
  452. 19:36and previous.
  453. 19:39Visually, you can think of this almost
  454. 19:41like a linked list. So, you might have
  455. 19:43some page of data you're looking at and
  456. 19:46altogether you think of this as the
  457. 19:48page, the previous pointer and the next
  458. 19:52pointer. Meaning, you can't just jump
  459. 19:54seven pages forward like you could with
  460. 19:57the previous example. So what that means
  461. 20:00is client side
  462. 20:03if you want your current page 17 and
  463. 20:06then you have the option to click 16 and
  464. 20:1015 and then we might have 18 and 19.
  465. 20:13This is not ideal
  466. 20:17for this type of pageionation. Now it's
  467. 20:21technically possible you could
  468. 20:24manipulate this. So, for example, you
  469. 20:26might have page 17 and then if the user
  470. 20:29clicked page 19, you could just go to
  471. 20:31the next pointer twice, but it's just
  472. 20:34not natural. It's like forcing it. So,
  473. 20:36if you want the user to be able to say,
  474. 20:39"Hey, yeah, I want page 36," then you're
  475. 20:42going to want to go with the offset
  476. 20:44approach. Or if you want this to be
  477. 20:46sorted by some arbitrary column,
  478. 20:54then you will want to go with the offset
  479. 20:56approach. So client side, the way you
  480. 20:58would use this is at the bottom of the
  481. 21:00page, you could have a load more
  482. 21:06or you can have an infinite scroll,
  483. 21:08meaning once you go to the bottom,
  484. 21:12it will just automatically load the next
  485. 21:15page. This is the perfect way to consume
  486. 21:17a cursor-based pageenated API. Now, one
  487. 21:20last thing to mention with the
  488. 21:21cursorbased approach is that it's the
  489. 21:23ideal choice for large data sets.
  490. 21:29So when you're using an offset, the
  491. 21:31database still has to do some work to
  492. 21:34jump that offset. You can think of it as
  493. 21:37just burning through all of those rows
  494. 21:39to get to where you're trying to go. But
  495. 21:41if you're working with a specific ID,
  496. 21:43the database is able to just jump to the
  497. 21:45proper location. So this is a much more
  498. 21:48friendly option for very large data sets
  499. 21:51because in theory every time you go an
  500. 21:53additional page on a regular offsetbased
  501. 21:56pageionation based API the query is
  502. 21:59going to take just a little bit longer
  503. 22:01and a little bit longer until you're way
  504. 22:03deep into the records and you have a
  505. 22:06very large offset and you're wasting
  506. 22:07compute power by not using the database
  507. 22:09in the most ideal way. This usually
  508. 22:12isn't a problem for medium to, you know,
  509. 22:15regular size data sets, but it is
  510. 22:16something to consider if you are working
  511. 22:18with large data. So, let's take a look
  512. 22:20at these approaches from the client's
  513. 22:21point of view. And I want you to think
  514. 22:23of the options of having multiple pages
  515. 22:25like we talked about earlier. If you're
  516. 22:28going to go this route, you pretty much
  517. 22:29want to use that offset because the user
  518. 22:33can provide an arbitrary page. likely in
  519. 22:35the URL you're going to see something
  520. 22:37like page or offset
  521. 22:41that you can just provide a value for
  522. 22:43and clicking these buttons just makes it
  523. 22:45easier for the option of a load more or
  524. 22:48an infinite scroll. There's one thing I
  525. 22:51wanted to call out.
  526. 22:54I think you can do this approach with
  527. 22:57either of these because basically with
  528. 22:59an offset base approach you could just
  529. 23:00load the next page and append that data.
  530. 23:03But the problem is if you have a current
  531. 23:06viewed data set. So this is the stuff on
  532. 23:08the page. It's already loaded in memory.
  533. 23:12What happens if we click load more but
  534. 23:15before we clicked load more data was
  535. 23:18added or removed that affects that
  536. 23:20offset? This could cause duplicate
  537. 23:22values in the view set. So let's go
  538. 23:26through a quick example. We're going to
  539. 23:28list some comments and let's say we are
  540. 23:32looking at these three. So these are
  541. 23:35added to our comments state and then we
  542. 23:38add some data that affects the data
  543. 23:40that's being retrieved.
  544. 23:43This could shift the pages. So we were
  545. 23:46originally looking at three. When we
  546. 23:48want to grab the next set of data to
  547. 23:50append it to our local state, it's going
  548. 23:53to grab from here. So you can see it
  549. 23:56crosses over this love it example twice.
  550. 24:01Additionally, this new comment is
  551. 24:03skipped over, which isn't probably the
  552. 24:05end of the world, but our current state
  553. 24:08is going to look like, "Hey, great
  554. 24:11videos.
  555. 24:15Love it."
  556. 24:18A second instance of love it.
  557. 24:22And then not bad.
  558. 24:25This would be avoided with a
  559. 24:27continuation token because that wouldn't
  560. 24:29have shifted with the insert of a new
  561. 24:31comment. So basically what you need to
  562. 24:33do is if you're appending to a local
  563. 24:35state, you need to dduplicate,
  564. 24:38get rid of any duplicate data so the
  565. 24:40visual doesn't show repeating values.
  566. 24:42Now this is all just talking about the
  567. 24:44local state. If you do a refresh, you're
  568. 24:46not going to have duplicate data. I'm
  569. 24:48talking about adjusting the state on the
  570. 24:50page as we go with data being changed on
  571. 24:53the back end. With a continuation token,
  572. 24:55this will be a seamless experience. You
  573. 24:57can just extend the state every time you
  574. 24:59load more. You're never going to have to
  575. 25:00worry about the duplicate data showing
  576. 25:02up. And then data such as this one, this
  577. 25:05great stuff that was added later,
  578. 25:08you can just ignore that as you extend
  579. 25:10the page. And then if you do a refresh,
  580. 25:13it'll be retrieved fresh. That's all I
  581. 25:14have in this lesson which was your
  582. 25:16introduction to pageionation and some of
  583. 25:18the different approaches. The next
  584. 25:20logical thing for you to do would be to
  585. 25:22implement this in some library. So build
  586. 25:24a backend, create multiple pages and
  587. 25:26then if you want you can learn to
  588. 25:28consume that on the client end as well.
  589. 25:30Thank you so much for watching.
  590. 25:31Hopefully these API videos have been
  591. 25:33really helpful. If so, please let me
  592. 25:34know. Or if there's some other topics
  593. 25:36you'd like me to discuss, leave a
  594. 25:37comment so I can adjust what type of
  595. 25:39material to focus on. Thank you so much
  596. 25:41for watching and I will see you in the
  597. 25:43next one. Peace out.

About this transcript

This page contains the full transcript of API Pagination - Offset and Cursor Pagination Explained - Backend Engineering by Caleb Curry, generated from the public captions YouTube serves with the video. The transcript has 4,182 words across 597 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.