I'm experiencing kind of weird error, I'm calling API (which written in golang) to get access token, that API returns the correct value for one time but if I send that API call again it returns 502 error code, then if I call that API once again it will return the correct value. this happens one after the other.
Looks like issue happened because of the load balancing. Normally round-robin routing policy is used in load balancing. For example, if you have two servers one request goes for the first one and other one goes for the other server. So for your question, the first request is going for the working server and other is going for the non-working server. Check whether your other servers are working properly.
You may need to check the circulation of IP data transmission between different computers under its control.
Related
Suppose I have an endpoint that supports creating new messages. I am avoiding the creation of two times the same message in the backend, in case the user tries to push the button twice (or in case the frontend app behaves strangely).
Currently for the duplicate action my server is responding with a 303 see other pointing to the previously created resource URL. But I see I could also use a 302 found. Which one seems more appropriate ?
Note that the duplicate avoidance strategy can be more complex (eg for an appointment we would check whether the POSTed appointment is within one hour of an existing one)
I recommend using HTTP Status Code 409: Conflict.
The 3XX family of status codes are generally used when the client needs to take additional action, such as redirection, to complete the request. More generally, status codes communicate back to the client what actions they need to take or provide them with necessary information about the request.
Generally for these kind of "bad" requests (such as repeated requests failing due to duplication) you would respond with a 400 status code to indicate to the client that there was an issue with their request and it was not processed. You could use the response to communicate more precisely the issue.
Also to consider, if the request is just "fire and forget" from the client then as long as you've handled the case for duplication and no more behavior is needed from the client it might be acceptable to send a 200 response. This tells the client "the request was received and handled appropriately, nothing more you need to do." However this is a bit deceptive as it does not indicate the error to the client or allow for any modified behavior.
The JSON:API specification defines:
A server MUST return 409 Conflict when processing a POST request to create a resource with a client-generated ID that already exists.
I have an RESTful API that calls another remote webservice. In general I have to query this remote service for every request that comes to my specific API function, and in my code I am wrapping and/or modifying parts of the result.
However it is possible that this remote service is not answering in time or throws an error. What is the most logical response that my API should throw then? I am specifically thinking about:
HTTP 500 - however this gives the client no information what is happening
HTTP 503 with a Retry-After header - then the client clearly sees this is an error and can query again later
HTTP 200 and returning an empty result
HTTP 200 and returning an error message or something like that
...or doing something completely different?
It all depends on what you want your API to convey to your client.
500: client cannot fetch his resource and does not know whether he should just bombard your server with another request, but at least knows it MIGHT exist
503: client cannot fetch his resource, but at least knows it MIGHT exist and can retry later in X amount of time.
200 *Empty response*: client is told his resource is empty and everything is ok, so probably will not come back while the resource could be not empty and was available a second later (Kind of misleading).
200 *Error message*: client is told everything is ok, but receives in your context an error message. (This is wrong and totally contradicting itself/yourself!)
My advice:
Do the 503
I am building an API and I was wondering is it worth having a method in an API that returns the status of the API whether its alive or not?
Or is this pointless, and its the API users job to be able to just make a call to the method that they need and if it doesn't return anything due to network issues they handle it as needed?
I think it's quite useful to have a status returned. On the one hand, you can provide more statuses than 'alive' or not and make your API more poweful, and on the other hand, it's more useful for the user, since you can tell him exactly what's going on (e.g. 'maintainance').
But if your WebService isn't available at all due to network issues, then, of course, it's up to the user to catch that exception. But that's not the point, I guess, and it's not something you could control with your API.
It's useless.
The information it returns is completely out of date the moment it is returned to you because the service may fail right after the status return call is dispatched.
Also, if you are load balancing the incoming requests and your status request gets routed to a failing node, the reply (or lack thereof) would look to the client like a problem with the whole API service. In the meantime, all the other nodes could be happily servicing requests. Now your client will think that the whole API service is down but subsequent requests would work just fine (assuming your load balancer would remove the failed node or restart it).
HTTP status codes returned from your application's requests are the correct way of indicating availability. Your clients of course have to be coded to tolerate and handle them.
What is wrong with standard HTTP response status codes? 503 Service Unavailable comes to mind. HTTP clients should already be able to handle that without writing any code special to your API.
Now, if the service is likely to be unavailable frequently and it is expensive for the client to discover that but cheap for the server, then it might be appropriate to have a separate 'health check' URL that can quickly let the client know that the service is available (at the time of the GET on the health check URL).
It is not necessary most of the time. At least when it returns simple true or false. It just makes client code more complicated because it has to call one more method. Even if your client received active=true from service, next useful call may still fail. Let you client make the calls that they need during normal execution and have them handle network, timeout and HTTP errors correctly. Very useful pattern for such cases is called Circuit Breaker.
The reasons where status check may be useful:
If all the normal calls are considered to be expensive there may be an advantage in first calling lightweight status-check method (just to avoid expensive call).
Service can have different statuses and client can change its behavior depending on these statuses.
It might also be worth looking into stateful protocols like XMPP.
I am trying to implement an API which uses the long-polling concept in Symfony framework.
Let's say that I have a table 'feeds' which can only grow (assume that users can insert thier feed from other interface).
I want to create a client-side real-time updated page. The idea is the following:
Client send an ajax request with timestamp of last modification (first time sends 0)
Server compares timestamp of client to timestamp, to retrieve all messages with bigger timestamp than the one sent by user
If there are newer messages, return them immediately to the client, with the timestamp of the latest one
On other hand, if there are no new messages, enter into a 2 minutes busy-wait loop, checking every 1-3 seconds (randomly) whether there are new messages.
When client receive servers answer, browser updates view and immediately sends a new ajax request.
In other words, instead of send an AJAX call every x seconds, the server holds the request till it has new information for us.
Having good experience with Symfony I tried to implement a simple demo of this api, and it works great. I had a problem of session blocking (the ajax call is held so access to the server is not possible), so I simply added the following to the action:
public function executeIndex(sfWebRequest $request)
{
session_write_close();
:
:
(see also this link)
Then I testes massive access to the API. 100 users works fine, 1000 everything crashes.
I realized that I have two problems:
For each access a new DB connection is opened
For each access the server executes a new process
For the first problem I tried to put persistent: true In my database.yml Doctrine connetor. When I monitored the server connections I saw that still each access to the API opens a new connection. So basically I am still blocked with the same two problems.
Does anyone have any idea or experience with this issue?? Or maybe I should give-up the idea of implementing my api with Symfony??
I think using symfony for this, is the wrong approach. Using Sockets would be much easier.
For example have a look at nodejs or ape-project (comet)
they both are able to handle much more current users than apache, lighttpd or nginx...
Apache creating different threads for each user and each thread have a separate database connection. that's why the db connection are high
I'm trying to set up a client-server architecture. I have one GKSession configured as a server, and two others as clients.
When either client uses the sendData:toAllPeers:WithDataMode:error method, it sends it not only to the server but to the other client.
I guess I could use the display name to exclude clients, so client data only goes to the server, but I'm not quite following why this is happening.
My server explicitly accepts a connection, via acceptConnectionFromPeer:error: But my client isn't accepting anything from anybody, it seems to be just silently finding the other client.
Should this be happening? I understand in a peer-peer setup you'd want peers to just find others; but in client-server, this seems a little weird.
Any clarification or advice would be greatly appreciated.
While a client cannot explicitly connect to another client, but the method sendData:toPeers:withDataMode:error: should allows you to send data directly from one client to another given that you have the correct peerId.