Skip to content

Support nested keys in alias for direct field mapping #276

@tjorim

Description

@tjorim

Is your feature request related to a problem? Please describe.
When working with nested JSON objects that include both a metadata field (e.g., a number field indicating the size of a list) and the actual list, it can be redundant to model both in a dataclass. For instance, if the number of items in the list corresponds directly to the length of the list, the number field becomes unnecessary.

Currently, I have to use an intermediary object to handle both fields, but this feels overly complex for a simple use case. It would be helpful if mashumaro could support directly mapping such nested structures into a list field without the need for an extra dataclass.

Describe the solution you'd like
I’d like the ability to use dot notation in the alias parameter of field_options to map a nested list directly. For example:

@dataclass
class VehicleApiResponse(ApiResponse):
    """Provides detailed data about a particular vehicle, including its stops."""

    vehicle: str  # Vehicle identifier
    stops: List[VehicleStop] = field(
        metadata=field_options(alias="stops.stop")
    )  # List of stop details

In this example, the stops.stop notation would allow me to map the nested stop list directly to a List[VehicleStop], skipping the need to model the number field explicitly.

Describe alternatives you've considered
I’ve currently use an intermediary dataclass to model both the number and the stop fields but thought about writing a custom deserialization function to extract the list manually. However, I’m unsure if these are the best approaches or if they’re even necessary for this case.

Additional context
Here’s a common example structure from an API response:

{
    "vehicle": "IC 1234",
    "stops": {
        "number": 2,
        "stop": [
            {"id": "S1", "station": "Station 1", "platform": "1"},
            {"id": "S2", "station": "Station 2", "platform": "2"}
        ]
    }
}

In this case, the number field corresponds to the length of the stop list, making it redundant to represent both explicitly in the dataclass.

I looked through the existing issues but didn’t find anything addressing this. However, it’s possible I might have missed something.

Example code of current implementation
@dataclass
class VehicleStop(DataClassORJSONMixin):
    """Represents a single stop in a journey for vehicles."""

    id: str  # Stop ID
    station: str  # Station name
    platform: str  # Platform name

@dataclass
class VehicleStops(DataClassORJSONMixin):
    """Holds the number of stops and a list of detailed stop information for vehicles."""

    number: int  # Number of stops
    stop: List[VehicleStop] = field(default_factory=list)  # List of stop details

@dataclass
class VehicleApiResponse(ApiResponse):
    """Provides detailed data about a particular vehicle, including its stops."""

    vehicle: str  # Vehicle identifier
    stops: VehicleStops  # Stops information

PS: I was also wondering if you accept anything besides crypto donations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions