REST API to pass indexed parameters for error messages - java

I'm designing a client and server system exchanging information using REST API. For i18n, the client to localized while server is always in English. In order to do that, only error code is sent from server to client and client will pick up the correct version of localized error message to display to the user.
Some error messages require indexed parameters. E.g. error message is "Can't find {0} on server {1}". I'm wondering what's the best practice to pass these indexed parameters (i.e. {0}, {1}) along with error code to the client so that the client can create the error message.

Can't you simply pass the errorcode + parameters in a single JSON object (or xml)?
{
"errorCode": "123",
"parameters": ["param0", "param1"]
}
Or am I missing something here?

Follow the suggestions from Nottingham & Wilde.
"This document defines a "problem detail" as a way to carry machine-readable details of errors in a HTTP response, to avoid the need to invent new error response formats for HTTP APIs."

Related

Unable to retrieve data from Sabre PriceQuoteServicesRQ 4.10 SOAP API: XML request schema validation failed: PriceQuoteInfo element is not complete

I have a problem when trying to retrieve data from Manage Price Quote Details (PriceQuoteServicesRQ) 4.10 Sabre SOAP API.
I generated Java classes using the WSDL from Sabre website (https://developer.sabre.com/docs/soap_apis/air/fulfill/manage_price_quote_details/resources).
I am constructing my request object in a following way:
ReservationTypeShort reservation = new ReservationTypeShort();
reservation.setValue("YEZUYS");
PriceQuoteInfoSearchParameters info = new PriceQuoteInfoSearchParameters();
info.setReservation(reservation);
PriceQuoteSearchParameters searchParameters = new PriceQuoteSearchParameters();
searchParameters.getPriceQuoteInfo().add(info);
searchParameters.setResultType(StringResultType.S);
GetPriceQuoteRQ req = new GetPriceQuoteRQ();
req.setSearchParameters(searchParameters);
req.setVersion("4.1.0");
I pretty-printed the object and this is what I got:
"priceQuoteInfo" : [ {
"reservation" : {
"value" : "YEZUYS",
"createDate" : null
},
"status" : [ ],
"type" : null,
"priceQuote" : [ ],
"travelItinerary" : null
} ],
So according to their documentation:
I am supplying all fields that are necessary, however it still doesn't work for me.
Did anybody else had the same problem? What am I missing/what am I doing wrong?
This is the error message I am getting:
XML request schema validation failed: PriceQuoteInfo element is not complete. One of the following fields: Status, Type, PriceQuote, TravelItinerary should be used. Please amend your request and try again.
What I have tried so far?
I asked Sabre Support for help, but they responded with a message that basically says "it works on my end".
I intercepted the XML body:
<ns5:GetPriceQuoteRQ version="4.1.0">
<ns5:SearchParameters resultType="S">
<ns5:PriceQuoteInfo>
<ns5:Reservation>YEZUYS</ns5:Reservation>
</ns5:PriceQuoteInfo>
</ns5:SearchParameters>
</ns5:GetPriceQuoteRQ>
I was missing an empty element <PriceQuote/> in my request.
It can be added by doing:
PriceQuoteInfoSearchParameters info = new PriceQuoteInfoSearchParameters();
info.setReservation(reservation);
info.getPriceQuote().add(new PriceQuoteSearch());
So according to their documentation I am supplying all fields that are necessary [...]
By documentation do you mean the WSDL or some human readable documentation (like PDF, DOCX, web pages, etc)? According to the error message you get, your SOAP request isn't valid. Sabre Support responding with "it works on my end" is another way of saying that you are not doing something correctly on your end. You need to troubleshoot your request.
From what I see, the error message is saying Status, Type, PriceQuote, and TravelItinerary but you are sending status, type, priceQuote, and travelItinerary. XML is case sensitive, and it's possible the service field names are too, so this might be the first thing to check.
Then, two of your fields (type and travelItinerary) are null. Also, priceQuote is empty. Is that OK? This is the next thing to check.
The object you pretty-printed shows a JSON format. Is this actually the format you are sending on the wire to the service? SOAP wants XML, not JSON. You also mention you generated the code from the WSDL. Using what framework or library? Does the generated code send XML?
Like I said, you need to troubleshoot the call:
download SoapUI
feed the WSDL file to SoapUI so that it can generate sample requests for you
fill in those request with real data and make calls to the web service until you get back a successful and expected response
using the same parameters from 3) in your code, perform the same call using your code
use SoapUI's monitoring tools to intercept the request at 4) and inspect the SOAP message you are sending
check the request you are making with your code against the successful request you got by using SoapUI directly
correct any differences until your request made by code is like the one send from SoapUI and it returns a successful and expected response.

REST: Tell client to send only csv and text format

In restfull WS, how to tell client to send only csv and text format file.
In content-type header, client set the format in which it is sending request and in Accept header, client set the format in which it want to accept response.
But how to tell client to send only content-type csv or file ? Is this through some documentation ?
The 415 status code seems to be suitable for this situation:
6.5.13. 415 Unsupported Media Type
The 415 (Unsupported Media Type) status code indicates that the
origin server is refusing to service the request because the payload
is in a format not supported by this method on the target resource.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
The response payload could contain a list of the media types supported by the server.
Image you have an endpoint called /textfiles - the developer using your API is usually reading your documentation on how to implement this endpoint. Unless you're not doing some auto-discovery magic (which I guess is still not common).
If we take Facebook for example, they just state in their documentation which files you can send:
We accept the following files: 3g2, 3gp, 3gpp, [...]
Your question:
But how to tell client to send only content-type csv or file ?
is also a bit unclear. When the user has sent the request, he already attached the files he thought he could send. So here you would rather send an error with a message, which files are allowed. So are we talking about some "pre"-requests here?
From a backend developers point of view I can just tell you: It's in the documentation. Handle errors properly, document and your implementing developer will not hate you :)
if i develop a restful application using spring i would set the produces attribute to return csv or plain text ( https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html) . if the client tries to request a resource other than csv or text it will recieve an error . probably 415

Proper Http status codes for uploading files on rest end point

We are developing an application that allows a user to upload file on rest end point.
Could someone please guide if it is correct to send 400 error code for the failure of following validation scenario:
1) The Length of file name exceeds permissible limit.
2) File name contains special characters
3) Uploaded file was empty
4) The System failed to read the uploaded file from disk.
Regards,
Tarun
The Length of file name exceeds permissible limit.
I think the 400 is not an appropriate because syntax of the request is correct in this case. The 422 Unprocessable Entity is better in this case.
File name contains special characters
Illegal characters mean the syntax is broken. So 400 Bad Request is a proper response in this case. Someone may claim that a definition of illegal characters is needed so the server may authoritatively send 400.
Uploaded file was empty
I think it is not an error because an empty file is a legal file.
The System failed to read the uploaded file from disk.
Does the system mean the server? Then the server should return a 5xx response because it is not a client failure. In case of general read error the server should return 500.
EDIT:
Uploaded file was empty.
When application semantic forbids an empty file the 400 or 422 appropriate. More details about them is at 400 vs 422 response to POST of data
4xx statuses are for client-side errors, 5xx are for server-side errors. So, generally you need 4xx codes for your cases 1) to 3), while 4) should be a 5xx error.
Let’s first say that for your case 4), a simple HTTP 500 seems appropriate. If you want to indicate that the client could try again later, HTTP 503 would be more suitable.
Now for 1) to 3): According to RFC 2616, HTTP 400 indicates syntax errors; this would usually be protocoll errors, e.g. invalid headers. Semantical or payload errors aren’t really defined in this generic RFC, however, (as Zaboj mentions) WebDAV offers HTTP 422, which seems suitable, though it’s not really meant for generic HTTP.
In the end, it doesn’t really matter which particular codes you send. If your upload fails with HTTP 400 or 422, in either case the client will perform some error routine (e.g. show or log the error message).
The important thing to know is that some codes can trigger client behaviour (e.g. HTTP 401 combined with certain headers can trigger an authentication dialog in a browser), and you should be aware of these side effects.
In my opinion, it is much more important to send a useful error description in the response body to help the client fix their problem, than finding the “perfect” HTTP status code. I know that REST zealots will disagree, but none of them will be able to give you the right HTTP status code for every situation.
That said, if you want to issue fine-grained error codes/messages for automated processing, you can introduce custom HTTP header fields, e.g.
X-MyApp-Error-Code: 2.1.6
X-MyApp-Error-Message: The uploaded file is empty
Then you would provide a documentation and/or SDK which reveals all possible error code values for X-MyApp-Error-Code to your API consumers.

Rest error codes/ success code

I am working on REST project using jersey. On success I am returning 200 code along with the json response for particular request. I know there are may different classifications of error codes, like server error which start with 500, client error which start with 400 etc. My question is suppose we are subtracting some value in database for example count, for example count in database is 5 and request comes to subtract 3, it is valid and i will send request but my business rule states that count cannot be less than zero, so if request comes 6, i cannot subtract that , so in that case should i actually send status code as 200 and send error information is json respose {"errorCode" : "1","errorMessage":""} so i should send different HTTP status code like 5## that there is server problem or 4## saying bad request.
Can anyone please suggest me good (in the sense which is restful and follow all standars) REST project on github which I can refer.
If any error occurs during request processing you should never send a 2XX status code. Why? Because 2XX indicates successful processing which in this particular situation did not happen.
When you send a value to be subtracted from another value in DB and the assumption is that the result can't be lower than 0 you should reply with 409 Conflict HTTP status code and clarification in a response body stating e.g.:
The request can't be completed since the result value will be lower than 0.
It would be 400 Bad Request if null e.g. is sent instead of a number.
In the particular use case, you mentioned, you should return 400 as status code (bad request). errorCode in the json is your business domain, so you can use what you want ( Also, take a look at JSend standard for sending the http "error status" in the response https://labs.omniti.com/labs/jsend )
You're exactly right: you should send an HTTP "400" for a client error, a "500" for a server error, etc; along with a specific error message.
You may or may not want more granular HTTP status codes (for example, "403" for client authentication failed, otherwise "400" for other client-related errors).
Are are two good lists you can use for guidance:
Common MS-Azure REST Error Codes
HTTP Status Codes
NOTE:
There is no "standard" per se. The two links I gave above are useful "examples". The "official" IETF RFC for HTTP 1.1 Error codes is RFC 2616:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

JSONRPC format different between Jsonrpc4j and go's rpc/jsonrpc

I was meet a problem when I tried used net/jsonrpc package to build a server and a Java client with jsonrpc4j
The problem is jsonrpc4j is when error happen, golang`s method will return error and encoding to json.
I got this json object in client
{"id": -6028374044949000, "result": null, "error": "some error return message"}
This object cast failed in java's json4j.
http://www.jsonrpc.org/specification#error_object
After I checked the jsonrpc page, it is said the error field MUST a json object with fields [code, message, date], the golang jsonrpc package not meet the require.
So I`m confused how to solve this.
Change the jsonrpc lib,
Just replace the rpc way to thrift/gRpc,
Avoid to return error but send error in reply and let Java check the response,
Or just edited the json4j or golang's source code ( I'm very horrible about this option)
Thanks for watch.
If you need JSON-RPC 2.0 support for Go you can try https://github.com/powerman/rpc-codec

Categories