Google Drive Api - PHP - Upload word doc - 400 Bad request - google-drive-api

My final aim is to allow user to upload some content on to a google drive word document in their individual account.
I am using the PHP example provided on https://developers.google.com/drive/v2/reference/files/insert#examples. When uploading a simple text file, it works fine.
Then (after wasting almost 8 hours with mimetype application/msword. Not sure why the docs don't make it easier to find such common details.) I changed the mimetype to application/vnd.google-apps.document with empty data, and it worked absolutely fine.
Then, I created a doc file on google drive web interface and then exported it to my machine. It was saved as docx. Then in the example, this file is used as the source for data, I keep getting Error calling POST https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart: (400) Bad Request error.
The error message does not even provide any more details as to what is wrong with the request.
[responseBody:protected] => {
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}

You probably have to put the Word file's content as a string into the $request['content']
If it's .DOCX the proper MIME-type is a:
application/vnd.openxmlformats-officedocument.wordprocessingml.document
Reference: MSDN Library
Well, how shall one tell what's wrong by the response, but not the request which produces it?
You probably could have just written "HTTP400 - the crap is not working" instead,
which would provide about an equal amount of information.
HTTP Response-Code #400 in general means,
That the HTTP request was malformed (e.g. is missing parameters, wasn't properly escaped, etc).
^ ...and this is certainly the correct answer - according to the sample response.
And this is exactly the reason why the information provided isn't sufficient to provide you with a straight answer. I'd also wish the API to have a little more details in the responses (especially on occasional file validation errors) - because sometimes one can only guess what's wrong "on the other side".
Best practice is to start from a very simple working version and add some complexity then.
If you'd wish to have the issue reviewed/resolved, you should add a sample request.
Doesn't even matter how the code looks like - when the request is obviously malformed.
Ordinary I offer web-scripting as a service, just currently kinda out-of-resources.

Related

Logic Apps + Form Recognizer unable to send PDF to service

I have an Azure Logic App that uses a Analyze Document for Prebuilt or Custom models (v3.0 API) action. The Custom Model is good, I can hit it with Postman with no issue.
When I try to get a PDF from Sharepoint and send it to the service, I get an error saying:
{
"error": {
"code": "InvalidRequest",
"message": "Invalid request.",
"innererror": {
"code": "InvalidContent",
"message": "The file is corrupted or format is unsupported. Refer to documentation for the list of supported formats."
}
}
}
I've tried:
Passing the Get file content directly to the Document/Image File Content input
Passing body('Get_file_content)['$content']
Passing concat('data:application/pdf;base64,',body('Get_file_content')['$content']
This one converts to PDF in a Base64-to-PDF tool so I know the Base64 is good
Then I found out that the service wants binary format:
Passing base64ToBinary(body('Get_file_content')['$content'])
Still no go
Why can I not send the file to the Form Recognizer service?
EDIT:
Thank you to #vijaya. They helped me see that the Document/Image URL parameter was not necessary. Leaving that blank and using the original Get File Content worked!
Issue is with content-type. You need to pass content-type along with content for analyze document. I have reproduced issue from my side and below are steps I followed,
Initially created logic app as shown below,
Logic app failed with error,
The file is corrupted or format is unsupported. Refer to documentation for the list of supported formats.
Next modified logic app as shown below,
In Compose action setting content as
outputs('Get_blob_content_(V2)')?['body']?['$content'] and passing content-type as application/pdf as we are dealing with pdf files.
In Analyze Document for Prebuilt or Custom models (v3.0 API) action, using outputs of compose in Document/Image File Content.
Logic app ran successfully as shown below,
Output of Analyze Document is as shown below,

Best API response format in Json

Which one is best for Rest API response ?
In here I return some meta information with actual data. Although I am not sure they need to use those meta information or not.
{
"version": "1.0.0",
"isError": false,
"statusCode": 200,
"message": "Permission Object",
"data": {
"id": 1,
"name": "user create",
"created_at": "2022-11-30T10:18:20.000000Z"
}
}
In second example I am returning only the relevant data.
{
"id": 1,
"name": "user create",
"created_at": "2022-11-30T10:18:20.000000Z"
}
Give me suggestion if there are other better way.
I noticed you've used the tag REST, so I assume you are thinking about a RESTful API implementation and have some knowledge about RESTful API design.
If you need some best practices, a couple of them I think are useful. here and here.
Looking at your examples, I would prefer the second option, the reasons are:
IsError can be determined by the HTTP response, e.g. 400, 500, 200, 201, so it's redundant.
Status and Message are also redundant when the response is successful but could be useful in an error state, like in ASP.NET, you can use the ProblemDetails response (you can customize the way you want).
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Unable to create a new user due to missing name",
"status": 400,
"traceId": "00-0aa7d64ad154a1e1853c413a0def982d-195d3558c90f7876-00"
}
version is an interesting one. Usually, it can be included in the request header or URL. If the API cannot handle the version requested, then it should return an error in the problem details.
Thus, I prefer the second option and send a problem details response when there is an error.
An open source CRM with more than 18K start on github uses Laravel-default api resource
Project Link
Code Example link
Pay attention to status codes
Reference
This one is super important. If there's one thing you need to remember from this article, this is probably it:
The worst thing your API could do is return an error response with a
200 OK status code.
It's simply bad semantics. Instead, return a meaningful status code that correctly describes the type of error.
Still, you might wonder, "But I'm sending error details in the response body as you recommended, so what's wrong with that?"
Let me tell you a story.
I once had to use an API that returned 200 OK for every response and indicated whether the request had succeeded via a status field:
{
"status": "success",
"data": {}
}
So even though the status was 200 OK, I could not be absolutely sure it didn't fail to process my request.
This kind of design is a real no-no because it breaks the trust between the API and their users. You come to fear that the API could be lying to you.
All of this is extremely un-RESTful. What should you do instead?
Make use of the status code and only use the response body to provide error details.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Expected at least two items in list."
}
JSON API is a format that works with HTTP. It delineates how clients should request or edit data from a server, and how the server should respond to said requests.

Error response for REST API

Below is the error response that my API is returning to the client:
{
"statusCode": "400",
"errors": [
{
"errorCode": "50009",
"fieldName": "bookingDate",
"errorMsg": "Input bookingDate must lie in the bracket: 20 Jan - 27 Jan, 2018"
}
]
}
Client cannot show the errorMsg returned by the API in the UI, but it needs bracket information i.e. (20 Jan - 27 Jan, 2018) while forming some more meaning errorMsg. So, client has to extract bracket information from the API response.
But, this can break the client's functionality if the text of the errorMsg is changed.
So, to make client's life easy, I would like to change the error response slightly like this:
{
"statusCode": "400",
"errors": [
{
"errorCode": "50009",
"fieldName": "bookingDate",
"errorMsg": "Input bookingDate must lie in the bracket: 20 Jan - 27 Jan, 2018",
"startDate": "20 Jan 2018",
"endDate": "27 Jan 2018"
}
]
}
So, is it the right way to add startDate and endDate into the error response (just for the client's benefit) or is there any other better way?
Thanks in advance.
You are free whatever information you want to add to your error response. If you it's really useful to you, there is no reason not to. Facebook does so. On the other hand I would try to not bloat an error response.
A well designed and decoupled REST API implies most of the error reasons with the help of the standard definitions of the HTTP error codes, which still should be documented within the API documentation. Given this, a developer of a client is able to know the exact error only by parsing the error status.
This also means that a client developer needs to check whatever he can, straight away, without sending any request to the back end. For example if the given date range is valid.
Stating this, if a returning error code cannot be used to figure out the exact problem of the request, the design of the API interface might be not optimal.
Although as REST is only a concept, it's nearly impossible to implement a perfect RESTfull API, therefor there are always exceptions, IMHO.
Although this question tends to attract opinion-based answers, I will try to give some perhaps helpful hints.
Your API seems to validate user input. This input may be invalid for various reasons (e.g. no parseable date, date in the past etc.). This can never be reflected only via HTTP status codes and as such, returning an HTTP 400 and a validation error message, as you already do, is good practice.
This validation error message should be human-readable and it should be okay for the client to display it to the user. If a field name is included (as it is in your example), the client can even highlight the associated input field and display the error message next to it.
If the consumer of your API is not a UI, but some kind of automated service, then error related technical fields may fit the needs more. (And this is where opinions come into play: Many people say that the API should be agnostic of the consuming client types). But I think in your case, you should rather investigate why the client is unable to display the errorMsg - this should be the best and most flexible way to go to add additional validations in the future.

Suggested JSON structure for Exceptions?

Out of curiosity, are there any popular standards for returning server side exceptions (and corresponding details) in an API that returns JSON? The exceptions could be anything from uncaught exceptions in the code or thrown exceptions put in place by the developer.
Currently I'm setting the HTTP Status Code according to their Wiki definitions'
My JSON response would look something like this:
HTTP Code: 401
{'error': 'Authentication required.', 'message': 'You must be authenticated to perform that action.'}
You can take a look at JSON-RPC (http://en.wikipedia.org/wiki/JSON-RPC).
In case of success, the response is like this:
{
"result": ...(returned data)...
...
}
and in case of error, the response is like that:
{
"error": ...(error details)...
...
}
When the error occured, "error" property must be present and "result" property must not be returned. In case there was no error, "error" property must not be set. This way you can distinguish errors from successful responses based solely on the content of the response, without the need to check the headers (like response codes).
The standard structure of native ECMAScript error objects is:
{
name: ...,
message: ...
}
where "name" is the type of the error (the name of the corresponding constructor, like "Error", "SyntaxError", etc.). In your example, you could use the name "AuthentificationError", for instance.
Yes you can do the same.
As we know that Web servers allow us to create custom error pages for HTTP errors, in those custom error pages you have to serve the JSON reply
Example:
Add the following to your WEB-INF/web.xml:
<error-page>
<error-code>401</error-code>
<location>/autherror.jsp</location>
</error-page>
In the autherror.jsp file code the required logic to accomplish your needed JSON reply.
Try being a bit more verbose regarding the error you are sending. This structure has been suggested in some places to give sufficient information both for users and developer using your API
"error":{
"code":"410",
"long":"410001",
"message":"cannot connect to DB",
"developer":"Connection to the DB was unsuccessful due to ...",
"documentation": "mysite.com/help/errors/..."
}
Return the correct HTTP code for error. It is bad practice to return code 200 with error.
Extend the code with your own error IDs
Provide short message that roughly outlines the cause of the error. Consider adding more detailed message for the developers. Have in mind that API error messages are 99.9% of the time read by developers so make them happy by providing technical details (within reason) so that they can resolve ASAP.
In case you keep public documentation about your api and error codes, simply add the url.

Why should JSON have a status property

I stumbled over a practice that I found to be quite widespread. I even found a web page that gave this a name, but I forgot the name and am not able to find that page on google anymore.
The practice is that every JSON response from a REST service should have the following structure:
{
"status": "ok",
"data": { ... }
}
or in an error case:
{
"status": "error",
"message": "Something went wrong"
}
My question: What is the point why such a "status" property should be required in the JSON? In my opinion that is what HTTP status codes were made for.
REST uses the HTTP means of communication between client and server, for example the "DELETE" verb should be used for deleting. In the same way, 404 should be used if a resource is not found, etc. So inline with that thinking, any error cases should be encoded properly in the HTTP status.
Are there specific reasons to return a HTTP 200 status code in an error case and have the error in the JSON instead? It just seems to make the javascript conditional branches more complex when processing the response.
I found some cases where status could be "redirect" to tell the application to redirect to a certain URL. But if the proper HTTP status code was used, the browser would perform the redirection "for free", maintaining the browsing history properly.
I picture mainly two possible answers from you:
Either there are two quarreling communities with their favorite approach each (use HTTP status always vs. use HTTP status never)
or I am missing an important point and you'll tell me that although the HTTP status should be used for some cases, there are specific cases where a HTTP status does not fit and the "status" JSON property comes into play.
You are right. I think what you are seeing is a side-effect of people not doing REST correctly. Or just not doing REST at all. Using REST is not a pre-requisite for a well-designed application; there is no rule that webapps have to be REST-ful.
On the other hand, for the error condition, sometimes apps want to return a 200 code but an error to represent a business logic failure. The HTTP error codes don't always match the semantics of application business errors.
You are mixing two different Layers here:
HTTP is for establishing (high-level) connections and transferring data. The HTTP status codes thus informs you if and how the connection was established or why it was not. On a successful connection the body of the HTTP request could then contain anything (e.g. XML, JSON, etc.), thus these status code have to define a general meaning. It does not inform you about the correctness or type (e.g. error message or data) of the response.
When using JSON for interchanging data you could certainly omit the status property, however it is easier for you to parse the JSON, if you know if it includes the object you were requesting or an error message by just reading one property.
So, yes, it is perfectly normal to return a 200 status code and have a "status": "error" property in your JSON.
HTTP status codes can be caused by a lot of things, including load balancers, proxies, caches, firewalls, etc. None of these are going to modify your JSON output, unless they completely break it, which can also be treated as an error.
Bottom line: it's more reliable to do it via JSON.