Best API response format in Json - 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.

Related

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.

Restful API - JSON response with single or all error(s)

My current project, a restful API, validates a POST request to create a new user and multiple errors could occur (with HTTP status):
username not set (400 BadRequest)
username is taken (409 Conflict)
server can't establish db connection (500 Internal Server Error)
...
Should I immediatly send back a JSON response like this
{
"status": 400,
"Message": "No username is set"
}
if an error was detected or should is it better if I accumulate all errors like here:
{
"status": <HTTP STATUS CODE>,
"errors": [
{"message": "Username is not set."},
{"message": "Can't access the database."}
]
}
The last approach would not require multiple request to send a valid payload. But which status code should be used, if the username is not set (400 Bad Request) or the server can't access the database (500 Internal Server Error)?
I think if you foresee the need for multiple errors in one request, then the second JSON (with the multiple errors) is preferred. Another benefit of doing the multiple errors response is that as a user of your service, if i get back multiple errors, I can address them all at one shot, instead of addressing them one at a time as I get them.
After some research, the best (most standard) way to respond is a JSON structure of this form:
{
"error": {
"code": "400",
"message": "main error message here",
"target": "approx what the error came from",
"details": [
{
"code": "23-098a",
"message": "Disk drive has frozen up again. It needs to be replaced",
"target": "not sure what the target is"
}
],
"innererror": {
"trace": [ ... ],
"context": [ ... ]
}
}
}
The multiple errors you want to place would be individual elements in the "details" array. Using this structure you would still need some overall summary of the error, however the details would contain as many individual error messages as you want.
This is the format proposed by the OASIS data standard OASIS OData and seems to be the most standard option out there, however there does not seem to be high adoption rates of any standard at this point.
This also conforms to the JSON RPC 2.0 Spec as it requires that the error be an object in a "error" member, and that you have a code and message.
You can find the complete open source library that implements this at: Mendocino JSON Utilities. This library supports the JSON Objects as well as the exceptions.
The details are discussed in my blog post on Error Handling in JSON REST API

what is the default syntax of an API call?

Could someone help me to understand what a specific example of an API link would look like for the following API?
https://engradesandbox.com/docs/
They show examples in the documentation about what the JSON result/return of an API, but not an actual example of what a call would look like.
I've noticed this with most API's, they show the possible result data, but not the default url syntax. It's so frustrating, because looking through existing restful tutorials isn't very fruitful on the subject either.
How do you know what the actual API call should look like?
That actually does tell you you what to do.
All "calls" will be HTTP POST to the URL specified.
If you click on one of them, it takes you to a page that explains the input data for that method.
For example, see the class-behavior-add function. To call that function, you'd post to the URL they specify (https://api.engradesandbox.com/ as of this posting), and the content of your post would be XML or JSON that contains the fields specified here.
Example post data as JSON:
{
"apitask": "class-behavior-add",
"apikey": "your_api_key",
"ses": "session token id",
"clid": 1234567890,
"stuid": "student ID",
"date": 123456789,
"mark": 12,
"points": 123
}
Example post data as XML:
<engrade>
<apitask>class-behavior-add</apitask>
<apikey>your_api_key</apikey>
<ses>session token id</ses>
<clid>1234567890</clid>
<stuid>student ID</stuid>
<date>123456789</date>
<mark>12</mark>
<points>123</points>
</engrade>

Google Drive Api - PHP - Upload word doc - 400 Bad request

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.

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.