Does HTTP Content Negotiation apply to error messages? - rest

If a client sends an Accept header of application/xml, should the body of any error message (e.g. 500) also be xml? Or does the Accept header only apply to 200-level responses?

These sources imply that Content Negotiation should apply to error messages.
API Error Codes –
The payload format can change according to what MIME types your API uses: you might reply with a JSON payload including your specific error code and an optional error message, or with an XML body with similar information.
Twitter –
When the Twitter API returns error messages, it does so in your requested format.

Related

Test of API Gateway POST with Content-Type x-www-form-urlencoded returns 415 Unsupported Media Type

I'm trying to configure an API Gateway endpoint that receives an HTTP POST with a URL-encoded body. I simply want to convert the body to JSON and send it to SQS.
I cannot get the POST method test in the API Gateway console to succeed: it always results in 415 - Unsupported Media Type.
My POST "Integration Request" block is configured for "AWS Service" with SQS:
For Mapping Templates, I have added the application/x-www-form-urlencoded Content-Type with a corresponding template:
Finally, I configured my test with header Content-Type:x-www-form-urlencoded and provided a simple Request Body message=This%20is%20the%20message:
Unfortunately, the result is always "Unsupported Media Type". I cannot figure out why this is failing. The Mapping Template should be matching the Content-Type and applying the template.
Any suggestions what might be wrong here?
Thanks.

Jmeter error - "error":"unsupported_grant_type","error_description":"grant type not supported"

I was trying to setup Jmeter for Salesforce API testing. However getting the below error during Salesforce authorization:
"error":"unsupported_grant_type","error_description":"grant type not
supported"
I am passing the parameters as in the screenshots attached. The same parameters when passed in Postman works fine, however I am getting this error in Jmeter. Please let me know if I am making some error in passing the parameters in Jmeter.
Jmeter_HTTP Header Manager
Jmeter_HTTP Request
Jmeter_Sampler Result
According to HTTP Status Code 400 documentation
The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
Looking into your request, you're sending Content-Type header as application/json therefore your server expects JSON and you're providing something different.
My expectation is that you should switch to Body Data tab of the HTTP Request sampler and set the request body to look like:
Check out REST API Testing - How to Do it Right article for more information on REST APIs testing using JMeter.
I struggle with the same issue but it finally worked for me by doing the following:
Use Content-Type application/x-www-form-urlencoded in an HTTP Header Manager
Make sure is a POST Method and that you're using https
Not sure if it is necessary but in the Parameters tab make sure all (grant_type, password, client_secret_ client_id and username) are Content-Type application/x-www-form-urlencoded and check the URL Encode option for all
Only check "Follow Redirects" and "Use KeepAlive" options in the HTTP Request
hope it works for you too

Postman API Invalid Content-Type Header

I'm trying to test and API call for the Smartsheet API in Postman, but I keep receiving the same error. Even though I am defining the correct Content-Type as per the API documentation, the response I get is the error 1124, which is an invalid content-type header. I haven't been able to figure out exactly what is causing the issue. I have tried typing the header in the address and in the header tab in Postman, but neither option has given me the result I wanted.
Postman Screenshot
If I run the same request in Postman as your screenshot shows (except using my sheet ID), with the same headers that you're using, my request succeeds. i.e., if you're sending the Content-Type header with value application/json for this request, you should not be receiving the error message that you're reporting (1124 - invalid content-type header).
You would, however, receive that error message if you were either not including the Content-Type header at all OR if you were specifying an invalid value for the Content-Type header. A suggestion for troubleshooting: use Fiddler (or a similar tool) to examine the request that's being sent over the wire when you execute this request in Postman -- does it include the Content-Type header, and if so, what's the value of that header?
UPDATE:
Thanks for adding a screenshot of the body you're setting in Postman -- I believe that's the source of your issue. i.e., your Content-Type header says that the request body is in JSON format, but you're actually not sending JSON. To fix this: instead of specifying key/value pairs in Postman, select the raw radio button and specify the body in JSON format. Here's a screenshot of what that looks like:

For REST services that consume multiple formats, is there a generally accepted default Content Type?

If you have a REST service that accepts multiple formats:
JSON
XML
HTML form data
Is there a widely accepted 'default' Content Type or:
You pick it yourself based on the most frequent / common use case
Don't accept a missing content type, require it explicitly by consumer
For example, according to W3C the default content type for POST via HTML, is application/x-www-form-urlencoded.
I strongly suggest that a server should reject a request that has a missing or inappropriate Content-Type header. RFC 7231 Has an explicit code for such:
6.5.13. 415 Unsupported Media Type
The 415 (Unsupported Media Type) status code indicates that the
origin server is refusing to service the request because the payload
is in a format not supported by this method on the target resource.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
Even though it doesn't explicitly mention a missing Content-Type, this is the accepted practice. See: HTTP status code for unaccepted Content-Type in request
Just as you should send the content-type in a response, you should also expect to have a content-type in the request.
Also, it's quite common to expect the correct content-type, see Jira REST API for instance:
Make sure the content type in the request is set to 'application/json', as shown in the example.
Or Twilio, where they have a list of accepted content-type and say:
If the content-type header does not match the media, Twilio will reject the request.
And I'm pretty sure that also the Outlook Mail REST API needs it to be correctly set.
So, yes, I'd say:"Don't accept a missing content type".

What is the correct way to return a specialized HTTP response?

Let's say that in my RESTful interface I require the client to include some special header, just to indicate it's an authorized client. (Trust me on this; it's a requirement of the project.) If the HTTP request contains an incorrect value in this header, the server needs to send back an HTTP response that the client can recognize that it sent an unsupported value in the header.
What's the appropriate way to send back this information using HTTP?
I could send back a 400 Bad Request response, but how do I tell the client what the problem was exactly? The obvious option is to include some message in the body of the response. But (besides issues of i18n) is it really a good idea for the client to blindly display the contents of an error message?
I could send back a 400 Bad Request response, with a proprietary special header indicating that such-and-such header had the wrong code. This has the benefit that the client can actually process what the error was (as opposed to free text in the content). So does the 400 response then become a catch-all response, with the actual error in some proprietary header? Is this a good general pattern? But that almost suggests...
I could could send back some arbitrary 4XX response that has a proprietary meaning, such as 472 Bad Foo Header Value. Microsoft seems to have gone this route at times. The obvious problem is the possibility of clashes in a future version of HTTP (or with others who have done the same thing).
I suppose I'm leaning more toward 400 Bad Request with a special header indicating the error specialization. Any thoughts or experience with this use case?
If the special header is incorrectly formatted then you could send a
400 Bad request Response indicating that the header is wrong.
However If the sole purpose of the header is authorization and you reject the header, because of invalid value, then I would opt for:
403 - Forbidden, if you want the connection to be refused
401 - Unauthorized, if the client should try to reauthenticate
In the Response phrase you can indicate the reason for refusing the connection.