jsonapi-client icon indicating copy to clipboard operation
jsonapi-client copied to clipboard

202 Accepted response does not follow jsonapi spec

Open bradharmon opened this issue 7 years ago • 0 comments

After creating a new document, my server responds with a "202 Accepted" response, and I get the following backtrace:

Traceback (most recent call last):
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/resourceobject.py", line 598, in commit
    return self._commit_sync(custom_url, meta)
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/resourceobject.py", line 586, in _commit_sync
    return self._post_commit(status, result, location)
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/resourceobject.py", line 575, in _post_commit
    return self.session.read(result, location, no_cache=True).resource
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/session.py", line 342, in read
    no_cache=no_cache)
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/document.py", line 61, in __init__
    super(Document, self).__init__(session, json_data)
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/common.py", line 70, in __init__
    self._handle_data(data)
  File "/export1/code/shield/jsonapi-client/src/jsonapi_client/document.py", line 92, in _handle_data
    raise ValidationError('Data or errors is needed')
jsonapi_client.exceptions.ValidationError: Data or errors is needed

Doing a little digging, the response is processed by jsonapi-client in resourceobject.py: _post_commit:

    def _post_commit(self, status, result, location):
        if status in HttpStatus.HAS_RESOURCES:
            self._update_resource(result, location)

        # If no resources are returned (which is the case when 202 (Accepted)
        # is received for PATCH, for example).
        self.mark_clean()

        if status == HttpStatus.ACCEPTED_202:
            return self.session.read(result, location, no_cache=True).resource

In this case, when a 202 is received, self.session.read creates a new Document from the response which requires a document to be sent in the http response. However the jsonapi spec does not require this:

202 Accepted

If a request to create a resource has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code.

This is as opposed to the "201 Created" response which explicitly does require a document to be returned in the body:

201 Created ... The response MUST also include a document that contains the primary resource created.

Having said all of this, I think the code should read if status == HttpStatus.CREATED_201 which will result in returning Document.resource for 201 and NOT 202.

bradharmon avatar Dec 08 '17 16:12 bradharmon