Skip to content

Pagination

All list endpoints in the MyWarranties API support pagination to efficiently handle large datasets.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number (1-indexed)
limitinteger20Items per page (max: 100)

Example Request

http
GET /api/products?page=2&limit=10
Authorization: Bearer <token>

Response Format

Paginated responses include metadata about the current page and total results:

json
{
  "data": [
    {
      "id": 11,
      "name": "iPhone 15 Pro",
      "brand": "Apple",
      // ... product fields
    },
    // ... more items
  ],
  "meta": {
    "current_page": 2,
    "per_page": 10,
    "total": 45,
    "last_page": 5,
    "from": 11,
    "to": 20
  },
  "links": {
    "first": "/api/products?page=1&limit=10",
    "last": "/api/products?page=5&limit=10",
    "prev": "/api/products?page=1&limit=10",
    "next": "/api/products?page=3&limit=10"
  }
}

Response Fields

meta

FieldTypeDescription
current_pageintegerCurrent page number
per_pageintegerItems per page
totalintegerTotal number of items
last_pageintegerLast available page
fromintegerIndex of first item on page (1-indexed)
tointegerIndex of last item on page
FieldTypeDescription
firststring|nullURL to first page
laststring|nullURL to last page
prevstring|nullURL to previous page (null if on first page)
nextstring|nullURL to next page (null if on last page)

Paginated Endpoints

Products

http
GET /api/products?page=1&limit=20

Returns user's products with pagination.

Claims

http
GET /api/claims?page=1&limit=20

Returns user's warranty claims with pagination.

Claim Messages

http
GET /api/claims/messages/123?page=1&limit=50

Returns messages for a specific claim with pagination.

Admin Endpoints

http
GET /api/admin/products?page=1&limit=50
GET /api/admin/claims?page=1&limit=50
GET /api/admin/users?page=1&limit=50

Admin endpoints support higher limits (up to 100).

Limits

User RoleMax Items Per Page
CUSTOMER50
SUPPLIER50
RESELLER100
ADMIN100

Requesting more than the maximum will return the maximum allowed.

Examples

First Page

bash
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.my-warranties.nl/api/products?page=1&limit=20"
bash
# Use the 'next' link from previous response
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.my-warranties.nl/api/products?page=2&limit=20"

Last Page

bash
# Use the 'last' link or calculate from meta.last_page
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.my-warranties.nl/api/products?page=5&limit=20"

Client Implementation

JavaScript/TypeScript

typescript
interface PaginatedResponse<T> {
  data: T[];
  meta: {
    current_page: number;
    per_page: number;
    total: number;
    last_page: number;
    from: number;
    to: number;
  };
  links: {
    first: string | null;
    last: string | null;
    prev: string | null;
    next: string | null;
  };
}

async function fetchProducts(page: number = 1, limit: number = 20): Promise<PaginatedResponse<Product>> {
  const response = await fetch(
    `https://api.my-warranties.nl/api/products?page=${page}&limit=${limit}`,
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );
  return response.json();
}

// Usage
const result = await fetchProducts(1, 20);
console.log(`Showing ${result.meta.from}-${result.meta.to} of ${result.meta.total}`);

// Load next page
if (result.links.next) {
  const nextPage = await fetch(result.links.next).then(r => r.json());
}

React Hook

typescript
import { useState, useEffect } from 'react';

function useProducts(page: number = 1) {
  const [products, setProducts] = useState([]);
  const [meta, setMeta] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    fetchProducts(page, 20)
      .then(response => {
        setProducts(response.data);
        setMeta(response.meta);
      })
      .finally(() => setLoading(false));
  }, [page]);

  return { products, meta, loading };
}

// Component
function ProductList() {
  const [page, setPage] = useState(1);
  const { products, meta, loading } = useProducts(page);

  return (
    <div>
      {loading && <div>Loading...</div>}
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}

      <button
        onClick={() => setPage(p => p - 1)}
        disabled={!meta?.links.prev}
      >
        Previous
      </button>

      <span>Page {meta?.current_page} of {meta?.last_page}</span>

      <button
        onClick={() => setPage(p => p + 1)}
        disabled={!meta?.links.next}
      >
        Next
      </button>
    </div>
  );
}

Combining with Filters

Pagination works with filtering and sorting:

http
GET /api/products?page=2&limit=20&brand=Apple&sort=name&order=asc

The pagination metadata reflects the filtered results:

json
{
  "data": [ /* filtered products */ ],
  "meta": {
    "current_page": 2,
    "per_page": 20,
    "total": 15,  // Only 15 Apple products total
    "last_page": 1
  }
}

Performance

Database Optimization

  • Uses LIMIT and OFFSET in SQL queries
  • Indexed columns for efficient pagination
  • Query optimization for large datasets

Caching

  • Page results cached for 5 minutes
  • Cache key includes page, limit, and filters
  • Invalidated on data changes

Recommendations

  1. Use reasonable page sizes - 20-50 items is optimal
  2. Cache on client - Store fetched pages to avoid re-fetching
  3. Prefetch next page - Load next page in background
  4. Show total count - Display "Showing X-Y of Z items"
  5. Handle empty pages - Check if data array is empty

Errors

Invalid Page Number

json
{
  "error": "ValidationError",
  "message": "Page number must be >= 1",
  "code": "VALIDATION_INVALID_PAGE"
}

Limit Too Large

json
{
  "error": "ValidationError",
  "message": "Limit cannot exceed 100",
  "code": "VALIDATION_LIMIT_EXCEEDED",
  "details": {
    "max_limit": 100,
    "requested": 200
  }
}

MyWarranties - Warranty Management System