Is a good practice return a list of valid values in a Bad Request? - api

Example: An API endpoint that accepts in a PET field the values "DOG" and "PET". If it receives an request with the payload value with "RABBIT",
{
"animal": "RABBIT"
}
is a good practice return a 400 Bad Request (or even a 422 Unprocessable Entity) with the list of the valid values in the message?
Like "Invalid value for the animal field. Valid values: "DOG" and "CAT"? Or should i just return the http code?

You SHOULD (in the RFC 2119 sense) return a representation that explains the situation.
Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included representation to the user. -- RFC 7231

HTTP status code 400 is much general than 422. HTTP status code 422 feels like a much more appropriate response for situations where the data is understood, but is still not valid.
Even if you want to return 400 status code, it's correct. In any case, make sure that the error response in body explains what issue is.
HTTP/1.1 422 Unprocessable Entity
{
"message": "Validation Failed",
"errors": [
{
"field": "animal",
"code": "RABBIT is not valid value. Value must be either PET or DOG"
}
]
}

Related

Custom error status code with gqlgen + go gin

Recently I have been updating my GO REST APIs into graphQl API's and I came across issue where I am unable to customise my status code with gqlgen.
Response I got
Headers
Status Code: 200 OK
{
data: null,
errors: [
{message: "Unauthorized access", path: ["..."]}
]
}
Expected Header
Status Code: 401 UNAUTHORISED
Any help would be really appreciating!
Assume you have a gqlgen resolver similar to this:
func (r *queryResolver) SecretItems(ctx context.Context, userID string,
password string) ([]SecretItems, error) {
// ...
if !isAuthorized(userID, password) {
return nil, errors.New("Unauthorized access")
}
// ...
}
then the described behavior is expected. Errors should be returned as part of
the response body.
GraphQL is transport agnostic. While it is often served over HTTP, it might be
served over other client-server Protocols as well. Handling errors in the
response body requires no assumptions about the protocol. Hence, you shouldn't
rely on HTTP status codes.
Handling errors in the response body has another advantage: Assume a request
contains multiple queries. Some of them succeed, some of them fail. Then the
response can contain the result of successful queries under data and errors
related to failed queries under errors.
References:
GraphQL website
Specification: Response
Hasura: GraphQL vs REST
Possible reason why you expected a 401 status code
The gqlgen docs on
authentication contain an example
where 401 status code is returned.
Why? This happens in a http handler used as middleware on the chi http server.
The 401 status code is not returned by a GraphQL resolver.

qualtrics contacts api extRef

I am using the Qualtrics API to create contacts in a mailing list. In making a call to https://ca1.qualtrics.com/API/v3/mailinglists/ML_identity/contacts I am pushing a json string containing extRef. However, I keep getting the following response:
"httpStatus": "400 - Bad Request",
"error": {
"errorMessage": "Unexpected json key provided: extRef",
"errorCode": "RP_9"
},
The documentation clearly states extRef is what the field is called. What am I missing here?
The field should be externalDataRef instead of extRef (Qualtrics is inconsitent when it comes to that field). See: https://api.qualtrics.com/api-reference/reference/researchCore.json/paths/~1mailinglists~1{mailingListId}~1contacts/post
Note that the API call is specific to Research Core Contacts. XM Directory uses a different API call to add a contact.

Question about testIamPermissions method in Billing API

I'm trying to use cloudbilling.billingAccounts.testIamPermissions in the APIs Explorer, but I get an error.
API URL
https://developers.google.com/apis-explorer/?hl=ko#p/cloudbilling/v1/cloudbilling.billingAccounts.testIamPermissions?resource=billingAccounts%252F01183E-6A3E97-BE2C7A&resource=%257B%250A%257D&_h=1&
Error Result
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
The error message appears as 'Request contains an invalid argument', so the value entered in resource seems to be incorrect.
I entered billingAccounts / {billingAccountID} for resource, but I do not know why I get an error.
{billingAccountID} has entered the billing account ID you are using.
What value should be put in the resource?
You need to use your full ID "billingAccounts/012345-567890-ABCDEF`" as an string. Also avoid to share your private information for security reasons use examples instead.
Confirm that the other options of the API works for you.

Can't create replies to some existing youtube comments

I have a software, which allows you to create a reply to a comment on your youtube video. Therefore I use the youtube API v3 comments.insert method.
POST https://www.googleapis.com/youtube/v3/comments?part=id%2Csnippet&access_token=[access_token]
{
"snippet": {
"parentId": "parentId",
"textOriginal": "test message"
}
}
Most of the time the requests are successful. But for some comments I can't create replies this way. The API always returns:
{
"error": {
"errors": [
{
"domain": "youtube.comment",
"reason": "processingFailure",
"message": "The API server failed to successfully process the request. While this can be a transient error, it usually indicates that the requests input is invalid. Check the structure of the <code>comment</code> resource in the request body to ensure that it is valid.",
"locationType": "other",
"location": "body"
}
],
"code": 400,
"message": "The API server failed to successfully process the request. While this can be a transient error, it usually indicates that the requests input is invalid. Check the structure of the <code>comment</code> resource in the request body to ensure that it is valid."
}
}
I'm using a valid access token and the parentId is valid, too, because I can retrieve it through the API.
I took a look at the successful and failing requests, but didn't find any difference. So I assume that the request input isn't invalid as it is mentioned in the error message.
In my opinion this error isn't a transient error, because the same requests are still failing after some days.
I also tried to create a reply on such a comment through the API Explorer but the result was the same.
Does anyone have the same problems or am I doing something wrong?
When I go to the video and look at the comments directly, the comment with ID z13tjxdqnuygy1lga04cilcqxqipg1zbtbs has a "reply" option under it, while the comment with ID z13rgftjgw3bulyou04ccfnbjofztxg54yo0k does not. It seems that the user posted the comment via their Google+ page and disabled replies to their posts.

What HTTP status to use for good request with "bad" input?

I'm writing a microservice for validating promo codes. The client sends me a promo code and a product ID (json). There is the 200 OK case where the code is good, I apply a discount for their order. But there is an error-ish case where the promo code doesn't apply for this product. I'm unsure what response code to use.
Should this also be 200 OK (with some sort of message saying the validation of the code fails)?
Should it be 400 Bad Request?
Neither seems entirely appropriate, it's odd to say 200 OK when it wasn't "OK", however 4xx is usually for signifying a problem with the structure of the request / http protocol - and in this case the structure of the request is fine.
I'll second steveax. 422 seems like a good choice.
IMHO, you should never use 200 if the request failed.
Use an error code & if necessary, provide details in the response body:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{ "reason": 1, "text": "Invalid promo code." }
On second thought, I think 403 is a good fit here:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{ "reason": "bad_promo_code" }
Ultimately, it doesn't matter as long as it's documented.
I will suggest 409:
10.4.10 409 Conflict
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request.