Skip to content

Conversation

menthol
Copy link

@menthol menthol commented Jun 22, 2025

Description

This PR adds a new feature that allows dot notation in property names to be expanded into nested objects when using Data objects as resources and in TypeScript definitions. This is particularly useful when working with APIs that require or return nested JSON structures.

When using the MapOutputName or MapName attributes with dot notation (e.g., 'user.name'), the package can now generate nested arrays in the JSON output and nested TypeScript interfaces that match the structure of your JSON.

Configuration

The feature is controlled by a new configuration option in config/data.php:

'features' => [
    // Other features...
    'expand_dot_notation' => true, // Defaults to false if not specified
],

Benefits

  • Creates nested JSON structures from flat data objects when using Data objects as resources
  • Generates more intuitive TypeScript interfaces that match nested JSON structures
  • Improves readability and maintainability of both JSON output and TypeScript definitions
  • Makes it easier to work with APIs that expect nested data structures

Examples

Basic Example

class UserData extends Data
{
    public function __construct(
        #[MapOutputName('user.name')]
        public string $name,
        #[MapOutputName('user.profile.bio')]
        public string $userBio,
    ) {
    }
}

With expand_dot_notation enabled, this generates the following JSON:

{
    "user": {
        "name": "John Doe",
        "profile": {
            "bio": "Software developer"
        }
    }
}

Instead of the flat structure:

{
    "user.name": "John Doe",
    "user.profile.bio": "Software developer"
}

JSON:API Specification Example

When working with JSON:API specification, you often have relationships and attributes in a specific structure:

class ArticleData extends Data
{
    public function __construct(
        public int $id,
        #[MapOutputName('attributes.title')]
        public string $title,
        #[MapOutputName('attributes.content')]
        public string $content,
        #[MapOutputName('attributes.published_at')]
        public Carbon $publishedAt,
        #[MapOutputName('relationships.author.data')]
        public UserData $author,
        #[MapOutputName('relationships.comments.data')]
        public DataCollection $comments,
    ) {
    }
}

With expand_dot_notation enabled, this generates a JSON structure that perfectly matches the JSON:API specification:

{
    "id": 1,
    "attributes": {
        "title": "My First Article",
        "content": "This is the content of my article",
        "published_at": "2023-01-15T10:00:00Z"
    },
    "relationships": {
        "author": {
            "data": {
                "id": 1,
                "attributes": {
                  "name": "John Doe"
                }
            }
        },
        "comments": {
            "data": [
                {
                    "id": 1,
                    "attributes": {
                      "body": "Great article!"
                    }
                }
            ]
        }
    }
}

@menthol menthol changed the title Add feature to expand dot notation into nested arrays Add support for expanding dot notation in Data objects and TypeScript transformer Jun 22, 2025
@menthol menthol force-pushed the main branch 3 times, most recently from 67e5941 to c80deda Compare June 22, 2025 08:18
menthol added 2 commits June 28, 2025 08:31
- Introduced `expand_dot_notation` configuration in `data.php`, defaulting to `false`.
- Updated `TransformedDataResolver` to handle dot notation expansion using `Arr::set()`.
- Added documentation on nested data transformation with examples.
- Implemented tests for both enabled and disabled dot notation expansion.
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.

1 participant