On certain routes in my app, I have the current implementation at the moment.
API call -> do something -> error occurs -> return with proper error
API call -> do something -> no errors -> respond with 204 -> send WebSocket/PubSub notification with successful response + data
This approach allows me to notify anybody looking at the same page (like 2 people looking at the same order) of the status change, etc and if an error happens only the initiator sees it and deals with it.
Something about this feels wrong. Is there a more correct approach to achieve similar results?
Related
We have a route in our API which (when called) hits another 3rd party API.
e.g.
HTTP-GET /account/1
this returns some data from our database AND from .. say .. a 3rd party api like Auth0/Okta/SalesForce/whatever.
Now, if this 3rd party api call fails for any reason (fails == 4**, 5** or even a 200 OK but the content is some error message) then what error status code should I pass back to the client calling my API?
Initially I was thinking an HTTP-500-Server-Error but ... I'm not so sure now because I can prevent this error from occurring in the server if I return a nice error message back to the client. So then I thought, return an HTTP-200-OK which contains some key/value of the downstream issue/error ... but is this really OK (pun intended). To me, HTTP-200-OK is like the answer returned is really ok.
So i'm not sure what people do in this scenario.
I feel like an HTTP-500 is for errors that occur but haven't really been handled and/or accounted for.
Now, if this 3rd party api call fails for any reason (fails == 4**, 5** or even a 200 OK but the content is some error message) then what error status code should I pass back to the client calling my API?
APIs should be designed from the consumer's perspective. In most of situations, the API consumer wont't care if the request is fulfilled by the server they are firing a request to or by a downstream server.
If the request to the downstream server prevents your server from fulfilling the client request, you could go for 500 or 503. Alternatively you could return some cached data (if you have any) and return a 2xx status code.
I wanted to clarify on a usecase where i struggled to use GET method for a fetch operation.
I was asked to build a API to generate message from a predefined template. In the request i receive template-ID and the dynamic content which needs to be substituted. Dynamic content vary based on the template-ID.
I have designed like
Method = POST
URL pattern = /messagegenerator/v1/templateID
Body = Dynamic Content in the form of JSON
Response = Plain text message
Problem i faced: When i use GET method then template content should be passed in the URL which has length restriction. We wanted to prepare email message which has more dynamic content.
Ultimately this service won't create any resource but still i forced to use POST method.
Am i missing something?
Rest standard missing?
Is there any better way of doing this?
Is there any restrictions on the length of get URL parameters?
Although there is no url limit in the standard, there is this old advice about keeping your urls under 2000 characters: What is the maximum length of a URL in different browsers?
To the point: in your case sending a POST request with all data in the body is the best solution. Putting email body fragments, or anything that huge (if I understand correctly) into a url is very ugly :). Even if the request does not change anything on the server technically, you should use POST, yes.
You need to create a new API which supports http get method, because one API can't receive more than on http method.
As you pointed out, in REST the POST method is thought of creating a new resource. In your case a new resource "message" is generated indeed by posting the content even if you do not keep it on the server.
But you are using POST on a template! This should create a new template. To resolve this, add a subresource to the template resource so you can express that it is a message that is created.
I would even extend the URL by adding a "template" after the "v1" to make more explicit that it is the "template" resouce on the first level.
The only change necessary for that would be to modify the URL like this:
URL pattern = /messagegenerator/v1/template/<templateID>/message
So you could have (even if you do not implement it now):
GET on /messagegenerator/v1/template/ -> Deliver a list of templates
POST on /messagegenerator/v1/template/ -> Create a new template
DELETE on /messagegenerator/v1/template/<templateID> -> Remove a template
PUT on /messagegenerator/v1/template/<templateID> -> Modify a template
GET on /messagegenerator/v1/template/<templateID>/message -> Deliver a list of messages
POST on /messagegenerator/v1/template/<templateID>/message -> Create a new message
DELETE on /messagegenerator/v1/template/<templateID>/message/<messageID> -> Remove a message
PUT on /messagegenerator/v1/template/<templateID>/message/<messageID> -> Modify a message
So you could even manage and return old messages if you saved and assigned them an ID!
I am using PostMan as a REST client to test this API method Cisco ACL Analysis API. specifically POST /acl/trace or getAClTracksStd (first go to Policy Analysis)
Here is my PostMan HTTP test call
Does anyone who is familiar with PostMan understand why I am getting this "Request method 'GET' is not supported" error from the server? I am making a POST HTTP request, not GET.(Selected from Drop down menu) It make more sense for me to get a input invalid parameter error or something.
Just to show that the endpoint url works, heres a HTTP test request that works
(same link, host->host API -> GET /host/{startIndex}/{recordsToReturn}
There's two issues that I'm seeing with your REST call. First, the error you're seeing is because the call needs to be preceded by "https://". Second, remove the interface IDs parameter and values. You should get a response with data after making these changes.
Your json looks erronuous (comma after the destIp) - and the server probably always responds with a default confusing error message in this case. (Postman is very well tested and it sends POST).
I'm kind of new to Twitter streaming API. And I'm trying to get this beautiful and minimalist Scala wrapper for streaming API to get work.
But unfortunately I end up getting this weird error
HttpMethodDirector - Failure authenticating with BASIC 'Firehose'#stream.twitter.com:443
org.apache.commons.httpclient.HttpException: There was a problem connecting, HTTP code received was: 401 HTTP/1.1 401 Unauthorized
I checked the Authorization header and it all looks OK to me.
oauth_signature_method -> HMAC-SHA1,
oauth_signature -> YVbrIgokxdhbZ1AixdlLGaLWrfw=,
oauth_consumer_key -> ********************************,
oauth_version -> 1.0,
oauth_token -> ********************************************************,
oauth_timestamp -> 1379582015,
oauth_nonce -> wKqKGNNCtU2ND1j5xYR0oiTraBrF7i6m
The signature generation mechanism is also looks good to me as compared to
twitter official doc
You can further look to the actual .scala where the place it get generated
Can someone point me out where the issue is?
It looks like you're attempting to connect to the Firehose stream which is not publicly available. I work at Gnip and we have the Firehose and provide access to data from it (for a price). You should try connecting to a different method, in the documentation you provided they talk about available methods here.
If at all any error message should be returned with status code 405, what should it say? I suspect we should not return any, but just to make sure are there any best practices for this?
Given that 405 means Method not allowed, it's pretty obvious to anyone familiar with HTTP or other RESTful APIs what it means.
However, not all of your customers writing software with your APIs might have that prior experience, so it might be worth returning a message in the response that says something like, "This resource does not support the HTTP method PUT."
You might also want to include a hint in the returned message to tell the user to call OPTIONS to find out which methods are supported, assuming you implement it as such.