I'm trying to send a json payload in quartz scheduler. I have the header set to Content-type:application/json, but for some reason my json string is throwing an error: Uncaught error, unexpected token in json.
The original json that I'm sending to a graphql service looks like this:
{
GetAllAuthors{
id
name
}
}
But to make it work in quartz, I need to mimic a rest API call, which is why I tried using the following:
{ "query":{{""{\nGetAllAuthors {\nid\nname\n}\n\n}""}} }
The above is also giving me the "Uncaught error, unexpected token in json" error. Is there something that I'm missing or overlooking?
PS: I tried using an online json formatter and when I try to validate the above json, I get the following error:
Error: Parse error on line 2:
{ "query": { { "" {\ nGetA
--------------^
Expecting 'STRING', '}', got '{'
That's not valid Json. This is how it might look if it were:
{
"GetAllAuthors": [
"id",
"name"
]
}
but I suspect you're trying for something like this:
{
"GetAllAuthors": {
"id": 123,
"name": "James Brown"
}
}
Play here until you get it right: https://jsonlint.com/
Edit: I've not worked with GraphQL, but this page shows how a (non JSON) GraphQL query might be transferred over Http by POSTing JSON or GETting using querystrings: https://graphql.org/learn/serving-over-http/
I figured this out by testing through Mozilla's network tab - the correct format is:
{"query":"{\n GetAllAuthors{\n id\n name\n}\n}\n","variables":null, "operationName":null}
I have read many RESTful API design pattern resources.
But I'm not confident for deciding API.
It seems there does not not exist a standard JSON response format.
I need advice for my Json error response as below.
401
jwt token related fail
{
code:1,
message: "no access token"
}
{
code:2,
message: "invalid access token"
}
{
code:3,
message: "expired access token"
}
400
client's insufficient input parameter
{
code:20,
message: "input paramter 'search' is missing"
}
client's invalid value request
{
code:21,
message: "invalid serial no"
}
client's invalid request format
{
code:22,
message: "input parameter indate is invalid date format"
}
500
another mesh-up server's problem
{
code:30,
message: "no reply from external server API"
}
program logic error (ex. exception)
{
code:31,
message: "internal server error"
}
For 500 cases, I think client also needs more information.
And another concern is "Is error code needed?"
You could use Problem Details for HTTP APIs.
It's a nice format that can be extended easily to provide the client a good way to react on each error/problem appropriately.
https://www.rfc-editor.org/rfc/rfc7807
Here is an example taken from the RFC:
{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc",
"balance": 30,
"accounts": ["/account/12345", "/account/67890"]
}
I am writing a REST API and I have stumbled upon a problem. What is the best way to return the validation errors.
Until now I have been returning the error messages dumped into a general error code (let's say bad request for example)
{
"status": 400,
"error": {
"code": 1, // General bad request code
"message": [
"The Key \"a\" is missing",
"The Key \"b\" is missing",
"The Key \"c\" is missing",
"Incorrect Format for field \"y\""
]
}
)
I have researched a little more about how should a good API response should look like and I thought of the following options:
Stop at the first encountered error and return a response with the specific error code
{
"status": 400, //Same as the HTTP header returned
"error" {
"code": 1, // Specific field validation error code
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info" => "www.api.com/help/errors/1"
}
)
Parse all the request data and return multiple field validation errors.
{
"status": 400,
"error": {
"code": 1 //General bad Request code
"message": "Bad Request",
"developer_message": "Field validation errors."
"more_info": "www.api.com/help/errors/1",
"error_details": {
0: {
"code": 2 // Specific field validation error code
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info": "www.api.com/help/errors/2"
},
1: {
"code": 3 // Specific field validation error code
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
"more_info": "www.api.com/help/errors/3"
}
}
}
}
In my opinion option 2 would be the right way (it gives more useful information to the developers/end users and the server load might be lower(less requests/no need to revalidate valid data/no need to compute the signature and authenticate the user)), but I am wandering what are the best practices, and if there is another way to treat this kind of problems.
Also i think option 1 is still valid if i get a single fatal error in the flow of the script.(not validation errors)
Please note that the code is just a simple array just so it is easier to follow. The response format will be JSON or XML.
Let's look to Facebook's Graph API. That is hit hard, and a great many errors are most likely generated. Here is what Facebook returns on an API error:
{
"error": {
"message": "Message describing the error",
"type": "OAuthException",
"code": 190,
"error_subcode": 460,
"error_user_title": "A title",
"error_user_msg": "A message"
}
}
They try to make the Graph API as useful as possible, but they seem return a specific error with a code and a subcode (Ref). The fact that each error has its own code means it's easier to search for said code or message as a starting point for debugging. That's probably why they don't accumulate error messages in their official error response. If it's good enough and convenient for Facebook, it's probably good enough for us.
Sample error responses:
{
"error": {
"message": "(#200) Must have a valid access_token to access this endpoint",
"type": "OAuthException",
"code": 200
}
}
and
"error": {
"message": "(#604) Your statement is not indexable. The WHERE clause must contain
an indexable column. Such columns are marked with * in the tables linked from
http://developers.facebook.com/docs/reference/fql ",
"type": "OAuthException",
"code": 604
}
Then there is JSend which "is a specification that lays down some rules for how JSON responses from web servers should be formatted." Their goal is:
There are lots of web services out there providing JSON data, and each has its own way of formatting responses. Also, developers writing for JavaScript front-ends continually re-invent the wheel on communicating data from their servers. While there are many common patterns for structuring this data, there is no consistency in things like naming or types of responses. Also, this helps promote happiness and unity between backend developers and frontend designers, as everyone can come to expect a common approach to interacting with one another.
Here is a sample error message:
{
"status" : "fail",
"data" : { "title" : "A title is required" }
}
It looks like Facebook and this group trying to set like an industry standard are opting for your choice #1.
Bounty Question
In response to the bounty request of "if anyone went #2 and maybe has any improvements on it?", there is a design pattern from Pragmatic RESTful API that states:
Validation errors will need a field breakdown. This is best modeled by using a fixed top-level error code for validation failures and providing the detailed errors in an additional errors field, like so:
{
"code" : 1024,
"message" : "Validation Failed",
"errors" : [
{
"code" : 5432,
"field" : "first_name",
"message" : "First name cannot have fancy characters"
},
{
"code" : 5622,
"field" : "password",
"message" : "Password cannot be blank"
}
]
}
I have used #2 myself a couple times. Is it better than #1? I think that depends on what your API is being used for.
I like #2 because it gives a developer who is testing the API with some test calls a quick overview of all the errors/mistakes he made in a request, so he knows immediately which errors/mistakes he has to fix to make that request valid. If you return the errors one by one (like in #1) you have to keep retrying the request and cross fingers hoping it will be valid this time.
But as I said #2 is very useful for developers, but the reasons don't really apply to end users. End users don't usually care how it's implemented. Whether the software is doing 1 request which returns 5 errors or 5 subsequent requests which return 1 error each.
As long as it's handled well in the client, the end user shouldn't notice the difference. How to handle that of course very much depends on what the client actually is.
Next to speeding up the development, another benefit of #2 (in production) is that it requires less requests to be made, which of course decreases the server load.
I would like to know if anyone went #2 and maybe have any improvements on it so I opened a bounty.
Sure there are improvements to be made. As it is, there is some data in the body that can be omitted.
{
"status": 400,
"error": {
"code": 1 //General bad Request code
"message": "Bad Request",
"developer_message": "Field validation errors."
"more_info": "www.api.com/help/errors/1",
"error_details": {
0: {
"code": 2 // Specific field validation error code
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info": "www.api.com/help/errors/2"
},
1: {
(
"code": 3 // Specific field validation error code
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
"more_info": "www.api.com/help/errors/3"
)
}
)
With HTTP responses, the status code should not go in the body, but in the header. This means that "status": 400 and "message": "Bad Request" can be omitted here. 400 should be the response's status code, and 400 means Bad Request. It's a HTTP standard and doesn't have to be explained in the response. Also "developer_message": "Field validation errors." is kind of a duplicate, since the specific errors are already included in each seperate error, so we could leave that out.
That leaves
{
"error": {
"code": 1 //General bad Request code
"more_info": "www.api.com/help/errors/1",
"error_details": {
0: {
"code": 2 // Specific field validation error code
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info": "www.api.com/help/errors/2"
},
1: {
(
"code": 3 // Specific field validation error code
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
"more_info": "www.api.com/help/errors/3"
)
}
)
"code": 1 //General bad Request code
"more_info": "www.api.com/help/errors/1",
These 2 lines don't really make sense anymore now. They are also not required, since each error has it's own code and info link, so we might strip these lines as well, leaving this
{
"error": {
"error_details": {
0: {
"code": 2 // Specific field validation error code
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info": "www.api.com/help/errors/2"
},
1: {
(
"code": 3 // Specific field validation error code
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
"more_info": "www.api.com/help/errors/3"
)
}
)
The 400 status code already indicates there was an error, so you don't have to indicate "error": {error details} anymore, because we already know there was an error. The list of errors can simply become the root object:
[
{
"code": 2//Specificfieldvalidationerrorcode
"message": "Field \"x\" is missing from the array structure",
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
"more_info": "www.api.com/help/errors/2"
},
{
"code": 3//Specificfieldvalidationerrorcode
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
"more_info": "www.api.com/help/errors/3"
}
]
So all that's left in the body now is simply a list of errors.
The status code is specified in the response header.
The details are specified in the response body.
I recently worked against a Rest API that would return multiple warnings or errors in the results. Starting from your Sample #2, I would modify it as follows:
{
"status": 400,
"results" : null,
"warnings": {
0: {
// Build a warning message here, sample text to show concept
"code": 1 // Specific field validation error code
"message": "It is no longer neccessary to put .js on the URL"
}
}
"errors": {
0: {
"code": 2 // Specific field validation error code
"message": "Field \"x\" is missing from the array structure"
"developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
},
1: {
"code": 3 // Specific field validation error code
"message": "Incorrect Format for field \"y\"",
"developer_message": "The field \"y\" must be in the form of \"Y-m-d\""
}
}
}
This would provide you the ability to provide results, with multiple warnings or errors as needed in your response.
And yes, this does have some bloat in the structure, but it also provides an easy interface for a developer to always get their data back in the same structure.
I would also remove the following items as IMHO they should be in the API docs (how to find help using an error code) instead of on every error:
"more_info": "www.api.com/help/errors/2"
"more_info": "www.api.com/help/errors/3"
Along those same lines, I'm not sure if you need both the message and developer_message. They appear to be redundant and as if you are trying to provide user error messages from the API when the caller failed to provide data correctly.
First of all you would have provided documentation for the Rest API methods for the customers. So it is expected from the customer/developer to provide valid data for the parameters.
Now having said that #1 is the best way to do Rest API. A developer's responsibility is to reduce server usage to the maximum possible extent. So if you encounter any fatal error, Construct a response with the corresponding error code and error message and return it.
Moreover we cannot be sure that there are more errors after the one we encountered. So there is no point in parsing the rest of the data. It will not work well considering the worst case.
Personally I would give the users less detail and either dump errors needed to the developers in a database log table or system logs. Due to the fact you are using JSON and that is most common on Apache servers and your code looks likely to be php (but your code example with curly braces could be a number of languages originating from PASCAL eg. C, C# PERL, PHP, CSharp). Here is how to put output custom errors to the system logs if you do not already know how in php http://php.net/manual/en/function.syslog.php . If your are using a rarer configuration IIS with JSON and CSharp there are .NET libraries to do similar too. If you give your users too much information when an error occurs you are also giving a hacker in the future a way of probing your website.
API's are not for humans. Therefore you don't need to return detailed error texts. You can even return an error code which means "missing parameter". Just don't forget to document it well.