Skip to content

Separate Validation of the Client Submission from Resource Dependent checks #5385

Closed
@claytondaley

Description

@claytondaley

I was trying to figure out how to return a 409 error on uniqueness issues. When researching the possibility, I found several closed issues (#1848, #4509) and the logically related issue #3381. I'd like to make the case that handling validation and uniqueness (technically any database-dependent validation) should occur in two stages.

  1. As I mention in my response to #4509, I don't think it even makes sense to compare invalid client submissions to the database to discover resource-dependent validation issues.
  2. Avoiding database calls when catching validation issues in the client's submission should improve performance.
  3. Separating validation of the client submission from resource-dependent checks (like uniqueness) makes the detection of 409 errors much easier. Because 409 is "conflict with the existing resource", the pattern actually mirrors the spec.
  4. (EDIT 11/2017) I recently ran into issue Unique constraint prevents nested serializers from updating #2996. Separating the two phases of validation could reduce the complexity of this issue. Client-related validation issues (i.e. 400 errors) could still be enforced, but uniqueness (i.e. 409) errors ignored. It's not a perfect solution as non-PK uniqueness issues and concurrency issues should prevent a commit.

Reason (1) is actually the root cause of #3381. The implemented solution (#4217) was to make uniqueness checks robust to validation-derived issues.

Reason (3) is actually the most relevant to me. Right now, the ONLY way to distinguish a uniqueness issue in the handle exception stage is to introspect error messages. To make things worse django hardcodes these messages in ways that cannot be used by the detection code. To muddy the waters further, the error I get for uniqueness on a single id column is (according to the inline documentation) part of a "unique together" check. I'm not sure if I'm misunderstanding the inline documentation, but it would be annoying if a future "fix" for this issue invalidated my 409 detection code.

If two-pass validation is acceptable, I suggest returning a subclass of ValidationError (e.g. ResourceValidationError) so existing error handlers are unaffected. However, folks wanting to support 409 can check for the subclass and alter behavior accordingly. Eventually, this could be implemented in the core error handler with a settings flag.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions