Is there a way to set a timeout on the ProxyEndpoint (not the target)?

WILLIT51
Participant II

I am developing an API proxy that makes several service call-outs to various targets. Each service call-out has its own timeout set within the Service Call-Out policy, however I would also like to define a timeout for the whole API itself. I assumed I would be able to define a io.timeout.millis setting on the ProxyEndpoint, similar to the TargetEndpoint, but this setting does not exist. Is there another way to accomplish this?

Solved Solved
0 8 2,235
1 ACCEPTED SOLUTION

sarthak
Participant V

I agree to what @Mukundha Madhavan said.

But is the reasoning for timeout that if a client made a call and it is taking lets say 15 seconds to finish then the backend should timeout? Now normally the backend is represented by TargetConnection and hence it is simple. But in your case backend consists of multiple calls via service callouts. So you need a different way to do the timeout.

If that is true, then I think there may be a way to do it.

The answer is Proxy Chaining.

Chain two proxies. Your calls come to Proxy1 which then sends the calls to Proxy2. Proxy1 does not have any business logic apart from io.timeout.millis set in Target Connection.

Proxy2 has all the service callouts.

So if Proxy2's work is not finished in time then Proxy1 will timeout and send a custom error message to the client.

You can see details here: http://docs.apigee.com/api-services/content/connecting-proxies-other-proxies.

Does this work?

View solution in original post

8 REPLIES 8

sarthak
Participant V

@WILLIT51 I can't think of a way, on top of my head.

Can you elaborate the use case please? I may be able to provide some solution.

Sorry, I've now added a description. See above.

1>you can let the clients decide the timeouts

2> since you mention 'several' service callouts - have you considered wrapping them in nodejs? it could be much easier to implement with async modules

True. I could wrap all the call-outs in node. Although, we're trying to follow the best practice of utilizing the built-in policies as much as possible.

hi @WILLIT51, timeouts are set by a client.

In this case, a ProxyEndpoint acts like a server - so you can't set a timeout. The http clients connecting to this proxy can set a timeout while establishing a connection

That's the reason you see timeout setting for TargetEndpoint [it's the http client to the backend]

So like sarthak asked, what do you want to achieve by a timeout at proxy?

It's essentially to protect the API gateway from a long-running transaction in the event of a perfect storm of all back-end targets taking a long time to process (yet not long enough to timeout individually). It's also to protect clients that do not establish their own client-side timeout.

Suppose my API is a composite that calls target A (configured with a 90 sec timeout), target B (with 90 s), and target B (with 90 s). Now suppose a call is made to my API and call A takes 60 s, B takes 60 s, and C takes 60 s. None of these call-outs time-out individually, but the total response time of my API is 180 s. I'd like to protect my consumers against this by setting a 120 s timeout on the API proxy.

I see your point -- I suppose ideally the clients should assume responsibility for their own timeouts. It would be nice if I could establish one as well, just in case.

sarthak
Participant V

I agree to what @Mukundha Madhavan said.

But is the reasoning for timeout that if a client made a call and it is taking lets say 15 seconds to finish then the backend should timeout? Now normally the backend is represented by TargetConnection and hence it is simple. But in your case backend consists of multiple calls via service callouts. So you need a different way to do the timeout.

If that is true, then I think there may be a way to do it.

The answer is Proxy Chaining.

Chain two proxies. Your calls come to Proxy1 which then sends the calls to Proxy2. Proxy1 does not have any business logic apart from io.timeout.millis set in Target Connection.

Proxy2 has all the service callouts.

So if Proxy2's work is not finished in time then Proxy1 will timeout and send a custom error message to the client.

You can see details here: http://docs.apigee.com/api-services/content/connecting-proxies-other-proxies.

Does this work?

Yes, that would work. Good idea!

Apigee might also want to consider a future enhancement of adding a timeout setting to the ProxyEndpoint. That would be cleaner. But thanks for the work-around.