5 ms·
I disagree. I think pagination is a clumsy error prone kludge. That it performs better than the awful naive approach by additionally burdening the caller doesn’
by User23 4y ago
I disagree. I think pagination is a clumsy error prone kludge. That it performs better than the awful naive approach by additionally burdening the caller doesn’t remotely make it good. The correct approach is a buffered stream with proper flow control. Incidentally that’s what Transmission Control Protocol was invented for.
Probably the nicest way to expose this that fits contemporary sensibilities would be as a lazy sequence that does sensible prefetching and asks the server for more data as it’s iterated through.
- freedomben 4y agoI find pagination really annoying on the client, but the majority of the time it does seem like the client doesn't actually need the whole thing so it's a good (and often very necessary) performance optimization. For endpoints where that isn't the case, it's (usually) not too hard to allow a sentinel value for page size that means infinity, so the client really can get it all in one swoop.
- robertlagrant 4y agoWhat are you saying that would be different in practice? What advantages would it have?
- jayd16 4y agoNot sure I agree with the parent but thinking it through, you have a single connection and a cleaner life cycle. Streaming writes and reads could mean back-pressure is possible. A client can consume items as needed as opposed to mapping usage to a page size. There's no worry about wasting a full request on the last page with a single item. In fact there's no worry about round trips at all, it's just a matter of buffer back pressure that communicates the need for more or less. Hmm, when you think about it, its a pretty good way to go.
- User23 4y agoThat’s consistent with what I have in mind. I too think it’s pretty much best of both worlds. You get better efficiency than pagination with the convenience of an API that’s no different from fetching all the data.
- nerdponx 4y agoI worked with an API like this once, which streamed NDJSON one line at a time. I loved the amount of control that it gave me on the client side!
- giaour 4y ago> a lazy sequence that does sensible prefetching and asks the server for more data as it’s iterated through Isn't this an accurate description of cursor-based pagination? You can have the server hold the cursor and associate a request for the next page based on the client ID (like in the PostgreSQL wire protocol), or you can make the flow stateless (at the network level) by handing the client a ticket for the next page.
- jayd16 4y agoPagination implies many requests where as a streaming API would keep to a single request, no? No worry about multiple servers or juggling state.
- giaour 4y agoIt's still multiple requests on a streaming API if you're asking the client to notify you when it's ready for the next page. Most DB engines use TCP connection affinity to identify which cursor is in play, but the client still needs to send a packet asking for the next page. Both client and server need to keep the TCP connection open, which is state for both parties. I see you mentioned gRPC streams in a sibling comment, which are a great alternative to REST-based pagination, but they are highly stateful! Streams are built into the protocol, so a generic gRPC client will handle most of the state juggling that would have been your responsibility with a REST client.
- jayd16 4y agoThis is a bit inaccurate I think. You can make a RESTful api over gRPC. The protocol is irrelevant. An open connection is not a violation of statelessness. If anything, a streaming API where you can close the cursor upon completion and treat new requests as fully new is a lot less stateful. We're also talking about APIs in general, not just http REST. >It's still multiple requests on a streaming API Perhaps, but the requests can be pipelined. You don't need to wait for the response to complete before asking for more.
- 4y ago
- jayd16 4y ago>Probably the nicest way to expose this that fits contemporary sensibilities would be as a lazy sequence that does sensible prefetching and asks the server for more data as it’s iterated through. gRPC's streaming API is a good example. It has backpressure built in and you just need to configure the buffer sizes. Clients just consume items off the stream and async writes will suspend as needed.
- stevebmark 4y agoWhen dealing with the most common case (I think) for pagination, clients (web/native) requesting data, are you suggesting keep a long running websocket only to fetch data in response to new page requests? What benefit would that afford, given that the requests are pretty far apart in time? Or are you focusing more on the backend machine to machine case? In that case, some kind of automatic prefetching, lazy loading/yield setup sounds pretty nice if that's abstracted away when you want to iterate over a large dataset from a separate resource server. It's not a pattern I've used before, mainly because it's not often that one server wants to know everything that another server has.