Is it possible to consolidate multiple responses and send one response in NGINX
Asked Answered
R

1

6

I have Nginx/openresty and some other services running on one VM. Basically VM accepts requests on Openresty and then openresty forwards requests to appropriate service. e.g. below requests getting forwarded to ServiceA, ServiceB and ServiceC respectively. It is working fine.

Now I need to expose a new endpoint which could get the responses from all services A, B and C. and then return one consolidated response.

I cannot use multiple proxy_pass in my location, could someone suggest how can I achieve that? e.g.

http://server:80/services/refALL --> returns a consolidated response from A, B and C Services.

Room answered 17/9, 2017 at 18:28 Comment(2)
What kind of response is returned here? HTML, JSON, Text file? And how exactly does the combining process work?Acolyte
it will be simple response. HTML mostly or just Text StringsRoom
A
8

you can do it like below. Basically you capture response from other services and then combine them

location /services/refALL {
   content_by_lua_block {
      local respA = ngx.location.capture("/services/refA")
      local respB = ngx.location.capture("/services/refB")
      local respC = ngx.location.capture("/services/refC")

      ngx.say(respA.body .. respB.body .. respC.body)
   }
}
Acolyte answered 17/9, 2017 at 19:50 Comment(5)
Thats perfect. I just need to replace single quotes with curly braces. But it works great. Its working fine when status is 200 for all. But need to see if http status code of one of apis is not 200, then that need to be reported separately.Room
@Yogi, yes i mixed content_by_lua and content_by_lua_block syntax by mistake, corrected now in answer. For call failure you just need to check respA.status and take action based on the status.Acolyte
Great. So when finally ngx.say statement executes. Can I determine the http status code for this. Actually if at least one call fails out of all, I want to return NOT SUCCESS. Currently it is just returning 200 OK. How can I return 500.Room
Yes you can do ngx.status=500, but this must be done before any ngx.say happens else the code will be set to 200Acolyte
I noted this on #55931350 as well but I think this is strictly worse than doing it at application level because you lose parallelism of requests, no?Riki

© 2022 - 2024 — McMap. All rights reserved.