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 4 times, most recently from c80deda to 42f0b31 Compare June 28, 2025 06:32
@rubenvanassche
Copy link
Member

Like the idea, thanks for the PR!

Few remarks:

  • Can you remove the config setting? I'm not that big of a fan of extra config
  • Instead add a property to the existing MapOutputName called $expandDotNotation which is default false (I think in v5 this may be true but I don't want breaking code)
  • Feel free to create a MapDotExpandedOutputName attribute which is basically the MapOutputName attribute but extended and that bool true
  • Also take a look at the EmptyDataResolver since we probably need the logic also over there

If that's all resolved this one can me merged, note myself to check the docs and see how they fit in once merging.

@menthol
Copy link
Author

menthol commented Oct 16, 2025

I will update this PR as soon as possible

- 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.
- Introduced `MapDotExpandedName` and `MapDotExpandedOutputName` attributes for handling nested data transformations.
- Updated `MapName`, `MapOutputName`, and name resolver logic to support `expandDotNotation` functionality.
- Modified tests and documentation to reflect new features.
@menthol
Copy link
Author

menthol commented Oct 25, 2025

@rubenvanassche done

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.

2 participants