Cornices/cornice

JSON API response does not get delivered when the status_code is 204

PatrickSampaioGERU opened this issue · 5 comments

I'm using cornice version 3.4.3. I designed an API that when there is not data for a request i return this:

error_message = {'status': 204, 'title': 'Exception_Title','detail': 'Deailt of Exception' }
return HTTPNoContent(json=error_message, content_type='application/vnd.api+json')

And the client receives the response content as empty.

But when i return:

return HTTPOk(json=serialized_contacts.data)

It receives normally. I'm using cornice with *marshmallow. And the resource configuration of this endpoint is:

@shield_resource.get(
    permission='view',
    apispec_show=True,
    apispec_validate_for="body",
    apispec_response_schemas={200: Schema, },
)

HTTPNoContent (204) has no content by design, that has nothing to do with Cornice... more Pyramid which follows rfc: https://tools.ietf.org/html/rfc7231#section-6.3.5

If you go to pyramid.httpexceptions.HTTPNoContent class definition than you can clearly see that it has no content body: https://github.com/Pylons/pyramid/blob/master/src/pyramid/httpexceptions.py#L444

If you want to return error message (because something went wrong) than you should return one of sub classes of the HTTPError (https://github.com/Pylons/pyramid/blob/master/src/pyramid/httpexceptions.py#L33) appropriate to the type of your error.

Thanks, helped a lot!

@czekan do you know if am I able to override this behavior in any sense?

Why would you want that (to not comply with the RFC)?
If there is an error, like bad request payload or problem with data validation, you should return HTTPBadRequest (or other more suitable error) with appropriate message in the body.

204 (no content) simply means that request was successful and server has nothing to send back to the client

400 (bad request) means that there was a problem and you can specify the error message

If that's not the case than you can probably define your own HTTPNoContent class like that:

class HTTPNoContent(HTTPSuccessful):
    code = 204
    title = 'No Content'
    empty_body = False

and return it from your view. I must say that is a terrible idea.

My thought was like:
I have a GET API that in some cases happens to not have content for a given identifier, so i would return 204 No Content. But as explicit is better then implicit, i thought in sending a message in the body just to ensure that the client know that there is not content for that identifier, and in this case it would not be a 4XX, because there was no error.

Thanks for the attention.