可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Do standards or best practices exist for structuring JSON responses from an API? Obviously every application's data is different, so that much I'm not concerned with, but rather the "response boilerplate", if you will. An example of what I mean:
Successful request:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
Failed request:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
回答1:
Yes there are a couple of standards (albeit some liberties on the definition of standard) that have emerged:
- JSON API - JSON API covers creating and updating resources as well, not just responses.
- JSend - Simple and probably what you are already doing.
- OData JSON Protocol - Very complicated.
- HAL - Like OData but aiming to be HATEOAS like.
There are also JSON API description formats:
- Swagger
- JSON Schema (used by swagger but you could use it stand alone)
- WADL in JSON
- RAML
- HAL because HATEOAS in theory is self describing.
回答2:
Google JSON guide
Success response return data
{
"data": {
"id": 1001,
"name": "Wing"
}
}
Error response return error
{
"error": {
"code": 404,
"message": "ID not found"
}
}
and if your client is JS, you can using if ("error" in response) {}
to check if there is error.
回答3:
I guess a defacto standard has not really emerged (and may never).
But regardless, here is my take:
Successful request:
{
"status": "success",
"data": {
/* Application-specific data would go here. */
},
"message": null /* Or optional success message */
}
Failed request:
{
"status": "error",
"data": null, /* or optional error payload */
"message": "Error xyz has occurred"
}
Advantage: Same top level elements in both success and error cases
Disadvantage: No error code, but if you want, you can either change status to be a (success or failure) code, -or- you can add another top level item named "code".
回答4:
Assuming you question is about REST webservices design and more precisely concerning success/error.
I think there are 3 different types of design.
Use only HTTP Status code to indicate if there was an error and try to limit yourself to the standard ones (usually it should suffice).
- Pros: It is a standard independent of your api.
- Cons: Less information on what really happened.
Use HTTP Status + json body (even if it is an error). Define a uniform structure for errors (ex: code, message, reason, type, etc) and use it for errors, if it is a success then just return the expected json response.
- Pros: Still standard as you use the existing HTTP status codes and you return a json describing the error (you provide more information on what happened).
- Cons: The output json will vary depending if it is a error or success.
Forget the http status (ex: always status 200), always use json and add at the root of the response a boolean responseValid and a error object (code,message,etc) that will be populated if it is an error otherwise the other fields (success) are populated.
It's up to you to choose :)
Depending on the API I would choose 2 or 3 (I prefer 2 for json rest apis).
Another thing I have experienced in designing REST Api is the importance of documentation for each resource (url): the parameters, the body, the response, the headers etc + examples.
I would also recommend you to use jersey (jax-rs implementation) + genson (java/json databinding library).
You only have to drop genson + jersey in your classpath and json is automatically supported.
EDIT:
Solution 2 is the hardest to implement but the advantage is that you can nicely handle exceptions and not only business errors, initial effort is more important but you win on the long term.
Solution 3 is the easy to implement on both, server side and client but it's not so nice as you will have to encapsulate the objects you want to return in a response object containing also the responseValid + error.
回答5:
I will not be as arrogant to claim that this is a standard so I will use the "I prefer" form.
I prefer terse response (when requesting a list of /articles I want a JSON array of articles).
In my designs I use HTTP for status report, a 200 returns just the payload.
400 returns a message of what was wrong with request:
{"message" : "Missing parameter: 'param'"}
Return 404 if the model/controler/URI doesn't exist
If there was error with processing on my side, I return 501 with a message:
{"message" : "Could not connect to data store."}
From what I've seen quite a few REST-ish frameworks tend to be along these lines.
Rationale:
JSON is supposed to be a payload format, it's not a session protocol. The whole idea of verbose session-ish payloads comes from the XML/SOAP world and various misguided choices that created those bloated designs. After we realized all of it was a massive headache, the whole point of REST/JSON was to KISS it, and adhere to HTTP. I don't think that there is anything remotely standard in either JSend and especially not with the more verbose among them. XHR will react to HTTP response, if you use jQuery for your AJAX (like most do) you can use try
/catch
and done()
/fail()
callbacks to capture errors. I can't see how encapsulating status reports in JSON is any more useful than that.
回答6:
Following is the json format instagram is using
{
"meta": {
"error_type": "OAuthException",
"code": 400,
"error_message": "..."
}
"data": {
...
},
"pagination": {
"next_url": "...",
"next_max_id": "13872296"
}
}
回答7:
For what it's worth I do this differently. A successful call just has the JSON objects. I don't need a higher level JSON object that contains a success field indicating true and a payload field that has the JSON object. I just return the appropriate JSON object with a 200 or whatever is appropriate in the 200 range for the HTTP status in the header.
However, if there is an error (something in the 400 family) I return a well-formed JSON error object. For example, if the client is POSTing a User with an email address and phone number and one of these is malformed (i.e. I cannot insert it into my underlying database) I will return something like this:
{
"description" : "Validation Failed"
"errors" : [ {
"field" : "phoneNumber",
"message" : "Invalid phone number."
} ],
}
Important bits here are that the "field" property must match the JSON field exactly that could not be validated. This allows clients to know exactly what went wrong with their request. Also, "message" is in the locale of the request. If both the "emailAddress" and "phoneNumber" were invalid then the "errors" array would contain entries for both. A 409 (Conflict) JSON response body might look like this:
{
"description" : "Already Exists"
"errors" : [ {
"field" : "phoneNumber",
"message" : "Phone number already exists for another user."
} ],
}
With the HTTP status code and this JSON the client has all they need to respond to errors in a deterministic way and it does not create a new error standard that tries to complete replace HTTP status codes. Note, these only happen for the range of 400 errors. For anything in the 200 range I can just return whatever is appropriate. For me it is often a HAL-like JSON object but that doesn't really matter here.
The one thing I thought about adding was a numeric error code either in the the "errors" array entries or the root of the JSON object itself. But so far we haven't needed it.
回答8:
The RFC 7807: Problem Details for HTTP APIs is at the moment the closest thing we have to an official standard.
回答9:
Their is no agreement on the rest api response formats of big software giants - Google, Facebook, Twitter, Amazon and others, though many links have been provided in the answers above, where some people have tried to standardize the response format.
As needs of the API's can differ it is very difficult to get everyone on board and agree to some format. If you have millions of users using your API, why would you change your response format?
Following is my take on the response format inspired by Google, Twitter, Amazon and some posts on internet:
https://github.com/adnan-kamili/rest-api-response-format
Swagger file:
https://github.com/adnan-kamili/swagger-sample-template
回答10:
The point of JSON is that it is completely dynamic and flexible. Bend it to whatever whim you would like, because it's just a set of serialized JavaScript objects and arrays, rooted in a single node.
What the type of the rootnode is is up to you, what it contains is up to you, whether you send metadata along with the response is up to you, whether you set the mime-type to application/json
or leave it as text/plain
is up to you (as long as you know how to handle the edge cases).
Build a lightweight schema that you like.
Personally, I've found that analytics-tracking and mp3/ogg serving and image-gallery serving and text-messaging and network-packets for online gaming, and blog-posts and blog-comments all have very different requirements in terms of what is sent and what is received and how they should be consumed.
So the last thing I'd want, when doing all of that, is to try to make each one conform to the same boilerplate standard, which is based on XML2.0 or somesuch.
That said, there's a lot to be said for using schemas which make sense to you and are well thought out.
Just read some API responses, note what you like, criticize what you don't, write those criticisms down and understand why they rub you the wrong way, and then think about how to apply what you learned to what you need.
回答11:
JSON-RPC 2.0 defines a standard request and response format, and is a breath of fresh air after working with REST APIs.
回答12:
Best Response for web apis that can easily understand by mobile developers.
This is for "Success" Response
{
"ReturnCode":"1",
"ReturnMsg":"Successfull Transaction",
"ReturnValue":"",
"Data":{
"EmployeeName":"Admin",
"EmployeeID":1
}
}
This is for "Error" Response
{
"ReturnCode": "4",
"ReturnMsg": "Invalid Username and Password",
"ReturnValue": "",
"Data": {}
}