GardenMobile & interfaces

Separating API response envelopes from Dart models

A historical model-design note about shared error fields, typed data, and responses with different shapes.

An API response often has two layers: a shared envelope describing success or errors, and data whose type depends on the endpoint. This older Dart design explored that distinction.

Read the envelope first

{
    "error": true,
    "data": null,
    "errors": [
        {
            "code": 1029,
            "message": "User not found!."
        }
    ]
}

The source’s BaseResponse<T> grouped an error flag, typed data, and a list of structured errors. Subclasses supplied data conversion in each direction. That moves shared envelope parsing into one place, but introduces a contract between the base constructor and subclass conversion methods.

Keep endpoint data explicit

The brand-list example sketched this shape:

{
    "error": true,
    "data": [{"name": name, "id": id}],
    "errors": [
        {
            "code": 1029,
            "message": "User not found!."
        }
    ]
}

name and id are schematic values in that historical listing, not valid standalone JSON literals. The implementation mapped each record into a BrandModel and serialized the list back through toJson.

Different endpoints can have different envelopes

The login example placed token fields at the top level:

Error
{
    "error": true,
    "data": null,
    "errors": [
        {
            "code": 1029,
            "message": "User not found!."
        }
    ]
}

Successful
{
    "token_type": "Bearer",
    "expires_in": 1295998,
    "access_token": "EXAMPLE_ACCESS_TOKEN",
    "refresh_token": "EXAMPLE_REFRESH_TOKEN"
}

Those values are generic labels. An endpoint with this shape cannot be assumed to follow the same nested-data contract as the brand list.

The old example’s error flow also accessed the first error and mixed parsing with loading-state handling. An empty error list, malformed response, timeout, and HTTP error need distinct handling.

The original implementation listings carried real-name and company metadata, so this revision keeps the design explanation and response examples rather than importing those modules. No new model implementation or API request is claimed.

← Back to the garden