Representing operation can not be executed due to resource state
How to represent cases when an operation can't be executed because of a resource state e.g.:
- operation not allowed in case of replacedSsin, canceledSsin, stoppedEnterprise, deceasedPerson …
- specific case: constraint violation on DELETE
- duplicate key on POST for creation
- referencedResourceNotFound (currently being standardized as issue type under 400 badRequest)
In #126 and https://github.com/belgif/rest-guide/wiki/Input-validation-issue-types , it was decided to leave the modeling of the specific resource states out of the REST guide, because too dependent on business semantics that should be decided by functional WG. When functional WG decides how to manage them, we could reference their deliverable. Do we prefer html page per issue type like for REST guide problems?
We should still decide how such issues should be represented in a Problem response in general:
- as an issue type within a 400 badRequestProblem?
- as a "409 Conflict" problem type?
- other ideas...?
409 Conflict matches more precisely this use case than the more general 400 status code:
The HTTP 409 Conflict client error response status code indicates a request conflict with the current state of the target resource.
Downside of 409 is that it disallows bundling input validation and state conflict issues in a single response.
If deciding on 409:
- define a new Problem type for all these cases or define separate problem types for each specific case?
- should the contents of the problem have the same InputValidationProblem structure allowing multiple issues?
REST WG agrees on this distinction between 400 vs 409:
- 400: something wrong with input (abstraction whether "wrong input" is checked against the state of a resource)
- 409: problem to execute request bc of current state of a resource (not necessarily the one being manipulated)
For some use cases, this distinction may be difficult to make, it can be decided case-by-case.
referencedResourceNotFound will remain possible on badRequestProblem, as are (to-be-standardized) canceled/replaced ssin.
HTTP/1.1 400 Bad Request Content-Type: application/problem+json
{
"type": "urn:problem-type:belgif:badRequest",
"href": "https://www.belgif.be/specification/rest/api-guide/problems/badRequest.html",
"title": "Bad Request",
"status": 400,
"detail": "The input message is incorrect",
"instance": "urn:uuid:123456-1234-1235-4567489798",
"issues": [
{
"type": "urn:problem-type:belgif:input-validation:schemaViolation",
"title": "Input isn't valid with respect to schema",
"detail": "enterpriseNumber abc should be numeric",
"in": "path",
"name": "enterpriseNumber",
"value": "abc"
},
{
"type": "urn:problem-type:cbss:input-validation:replacedSsin",
"href": "https://example.cbss.be/problems/replacedSsin",
"title": "SSIN has been replaced. Use new SSIN.",
"detail": "SSIN 12345678901 has been replaced by 23456789012",
"in": "body",
"name": "boardMembers[0].ssin",
"value": "12345678901",
"replacedBy": "23456789012"
},
{
"type": "urn:problem-type:belgif:input-validation:referencedResourceNotFound",
"title": "Referenced resource not found",
"detail": "Referenced resource boardMembers[1].ssin = '98765432109' does not exist",
"in": "body",
"name": "boardMembers[1].ssin",
"value": "98765432109"
},
{
"type": "urn:problem-type:cbss:input-validation:invalidPeriod",
"title": "Period is invalid",
"detail": "endDate should be after startDate",
"in": "body",
"name": "boardMembers[0].period",
"value": {
"startDate": "2020-12-31",
"endDate": "2020-01-01"
}
}
]
}
remaining issues:
- is there a need for standardized problem types within 409 status code? e.g. in case of double key, or DELETE foreign key constraint or should it always be specific to API? For those, is a composite issue structure needed?
how to document the business issue types (for 409 and 400)? Create html pages, like for indvidual problem types e.g.
- https://www.belgif.be/specification/rest/problem-issues/person/replacedSsin.html
- https://www.belgif.be/specification/rest/problem-issues/index.html => will be worked out when first 'business' issue types are standardized
Besides the "rejected insert because of duplicate key" and "rejected delete because of foreign key constraint", another potential common 409 Conflict scenario is a "rejected update because of optimistic locking".
The REST guide already specifies that 409 should be used for these scenario's in fact:
https://www.belgif.be/specification/rest/api-guide/#create-resource
https://www.belgif.be/specification/rest/api-guide/#document-full-update https://www.belgif.be/specification/rest/api-guide/#document-partial-update
https://www.belgif.be/specification/rest/api-guide/#remove-document
In my opinion, as these were deemed "important" enough to deserve specific mention in the REST guide, it makes sense to create standard problem / issue types for them? If no standard types are provided, there will be no tooling support, and too much "friction" for the developer to correctly implement these guidelines.
edit: Looks like optimistic locking is not in scope for 409 Conflict, because it should be 412 (Precondition Failed) according to #37, at least when ETags are used to implement to locking. If it's implemented with a version property in the payload, then 409 makes sense.
@pvdbosch could you update this issue to clarify about the note in Meeting 2025-03-28:
"Note: #217 Representing operation can not be executed due to resource state (409) - didn't need change in guide Conflict)"
@pvdbosch could you update this issue to clarify about the note in Meeting 2025-03-28:
"Note: #217 Representing operation can not be executed due to resource state (409) - didn't need change in guide Conflict)"
After taking another look, I've created a PR: https://github.com/belgif/rest-guide/pull/229 to update the description of 409 Conflict:
- describe as conflict with state 'of data on the server' instead of 'of the resource'
- remove optimistic locking from description
Optimistic locking can be re-added as status 412 when #37 is treated.
The current description of badRequestProblem still seems OK ("The input message is incorrect. Look for more details in the issues property.")
You don't agree with my earlier remark that HTTP 409 would benefit from standardized problem / issue type?
In my opinion, as these were deemed "important" enough to deserve specific mention in the REST guide, it makes sense to create standard problem / issue types for them? If no standard types are provided, there will be no tooling support, and too much "friction" for the developer to correctly implement these guidelines.
You don't agree with my earlier remark that HTTP 409 would benefit from standardized problem / issue type?
Undecided yet; that point was still open for discussion in a WG.
Because 409 is about errors that the client usually needs to be able to handle (i.e. problems that it can't avoid by checks before sending the request), maybe we should always have a more specific problem type according to the specific use case? E.g. cause for not being able to send a document could be "approvalNeeded" or "documentUnsigned" which could be their own problem type. Do we need a common problem type to bundle these or is the common "409" status code enough?
#229 was merged and published; updating the description of 409 Conflict