Skip to content

Conversation

@Ajibose
Copy link

@Ajibose Ajibose commented Oct 4, 2025

Standardize API Responses with Resource & Collection

Overview

This PR implements a structured system for API responses in the @h3ravel/http package using Resources and Collections. The changes introduce a Laravel-inspired developer experience while keeping H3ravel’s unique style

Key features include:

  • Resource class: Wraps a single model or object and provides a toArray() method for serialization.
  • Collection class: Handles arrays of Resource objects, supports pagination metadata, and link structures.
  • JsonResource helper: Automatically formats single Resource or Collection responses into the standardized JSON structure

Changes

  1. Resource

    • Base class for single model API responses
    • Supports adding relationships via withRelation / withRelations
    • Provides toArray() to convert models and relationships into plain objects
  2. Collection

    • Wraps multiple Resource objects or plain objects
    • Supports pagination (meta) and links (links) in responses
    • Provides toArray() and json() methods for consistent output
  3. JsonResource

    • Detects whether a resource is a single Resource, Collection, or plain object
    • Formats JSON responses as:
      • Single resource: { data: { ... } }
      • Collection: { data: [...], meta: {...}, links: {...} }
    • Handles nested relationships automatically
  4. Tests

    • Full coverage for:
      • Resource serialization.
      • Collection with pagination and links
      • JsonResource transformations
      • Nested resources
    • Ensures consistent API response structure

Developer Experience

  • Returning a Resource from a controller produces { data: { ... } }
  • Returning a Collection produces { data: [...], meta: {...}, links: {...} }
  • Works seamlessly with nested relationships

Example Usage

// Single resource
const userResource = new Resource(user).withRelation('posts', user.posts)
return new JsonResource(event, userResource).json().body

// Collection with pagination
const users = [new Resource(user1), new Resource(user2)]
const collection = new Collection(users)
    .withPagination({ from: 1, to: 2, total: 10, perPage: 2 })
    .withLinks({ self: '/users', next: '/users?page=2' })

return new JsonResource(event, collection).json().body

How to run tests

pnpm vitest

@3m1n3nc3 3m1n3nc3 linked an issue Oct 5, 2025 that may be closed by this pull request
7 tasks
@3m1n3nc3
Copy link
Contributor

3m1n3nc3 commented Oct 5, 2025

image

You have failing build step during testing, probably due to missing imports.

@3m1n3nc3
Copy link
Contributor

3m1n3nc3 commented Oct 5, 2025

Additional notes:

  1. Pagination links should be auto generated based on the current request url and should work fluently with the @h3ravel/url package
  2. Please study Laravel's API Resource Docs and API Resource to get a better idea of what we expect overall

No need to rush through

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Add API Resource and Collection layer for consistent JSON responses

2 participants