Skip to content

Improve 422 validation error responses #6050

@kevinansfield

Description

@kevinansfield

Our current validation error format (not sure if this is consistent across the app?) looks like this:

{
    "errors": [
        {
            "message": "Value in [posts.title] exceeds maximum length of 150 characters.",
            "errorType": "ValidationError"
        },
        {
            "message": "Value in [posts.meta_title] exceeds maximum length of 150 characters.",
            "errorType": "ValidationError"
        }
    ]
}

This has a couple of issues when attempting to consume on the client side:

  • It's necessary to extract the invalid property name from the message string
  • The message is not suitable for display within in-line validations

Due to the above issues we don't currently have anything in our Ember Data adapters to take the error response and normalize it so that the errors are automatically picked up by Ember Data/DS.Errors and made available on the relevant model object.

There are two formats that are widely used with Ember Data and have built-in support:

ActiveModelSerializer format:

{
    "errors": {
        "title": ["Title cannot be longer than 150 characters."],
        "message": ["Meta Title cannot be longer than 150 characters."]
    }
}

JSON API format:

{
    "errors": [
        {
            "source": { "pointer": "/data/attributes/title" },
            "title":  "Value is too long",
            "detail": "Title cannot be longer than 150 characters."
        },
        {
            "source": { "pointer": "/data/attributes/meta_title" },
            "title": "Value is too long",
            "detail": "Meta Title cannot be longer than 150 characters."
        }
    ]
}

The JSON API format also allows for additional fields such as code for application-specific error codes or the meta field that can contain completely custom data.

i18n: If we are going to update our validation response format would it also be a good time to make accommodations for i18n support? To do so it would be best to provide a "key" for the localisation lookup, e.g. a generic validation.too_long or a more specific post.errors.title.too_long.

Perhaps the meta field would be best for that? That would allow us to both provide a localisation key and any other details that can be used for interpolation. For example:

"meta": {
    "i18n": {
        "key": "validation.too_long",
        "max_chars": 150
    }
}

Could map nicely to the translation key:

"validation.too_long": "cannot be longer than {{max_chars}} characters"


I'd like to get some discussion started on which direction we'd like move towards for two main reasons:

  1. Even though we've mostly eliminated hitting the server with invalid data from the admin client there are still some edge cases where automatic mapping would be useful.
  2. More importantly when we get to opening write-access through the public API and its out in the wild and in use it will be a lot more difficult to change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    affects:apiAffects the Ghost APIaffects:serverIssues relating to the server or core of Ghostlater[triage] Things we intend to work but are not immediate priorityneeds:info[triage] Blocked on missing information

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions