NGINX : Making two asynchronously calls to a backend server - nginx

I want to do the following using NGINX Module :
Nginx receives a request, checks if it has the key to decode the request in the cache(custom)
if YES, then decode request, obtain an ID from it and check if there is a value against this ID in a key-value store (asynchronously) and return it in the response
if NO, then get the new key from the key-value store (asynchronously) and then store this key in the cache and use it to decode the request. Obtain the ID and check if there is a value against this ID in the key-value store(asynchronously) and send it in the response.
I was able to figure out how to do step 1, i wrote an upstream module by referring openresty's nginx module from github. For achieving step 2 functionality, i tried creating a new upstream request in the process_header() function of the first upstream call (i.e getting the key from the store), but this didn't work. How to achieve this ?
Thanks in advance.

I see 2 approaches:
You may do it all in Lua using lua-nginx-module and lua-resty-redis library. Here you may find some info Configure-nginx-to-get-url-from-redis-with-key-and-proxy-the-url-to-other-server
Write nginx C module, use redis2-nginx-module as upstream module, send subrequest. Take a look at my answer to Subrequests are not sent or the request hangs It shows how to send subrequests.

Related

Can we do regex for Response so that Consumer can have values dynamically?

I have written regex for response but the .json files are are creating with some wierd values like ABSGDKJEUDSGASH,
Can some help me in these
Response:
'agent': value(consumer((anyNonBlankString())), producer("abcd"))
Created Stubs
\"agent\":\"CVCHFTMETQSEOLOQENTY\":
Can spring cloud contract support response dynamically as it supports request??
consumer() is related to stubbing, producer() is related to the generated test. The matching in the request part is to make sure that the incoming HTTP request on your WireMock server matches the criteria that you have specified. Now everything that you write in the response side is what WireMock will return if your HTTP request matches those criteria.
If you need to return a fixed value, use consumer('my agent').
If it doesn't matter what you receive as a response, you can use eg. consumer(anyNonBlankString()).
If you want to return the same value as what you received from the client you can do something like consumer(fromRequest().header('agent')).
Hope that helps! :)

Why should a client state http method?

We know the difference between POST and GET, but why should a client state the method type when issuing http requests? Why should it make a difference for the server? in the end, it is the server job to deal with those requests according to their URL and Content. either by redirecting, blocking or accepting and using data (existing in the URL or request body).
An endpoint can accept both GET and POST requests (along with PUT, PATCH and DELETE). If the client does not explicitly state what type of request they are sending, the server will interpret it as a GET request (the default).
Consider the following PHP example, sitting on https://api.example.com/resources/:
<?php
if ($_POST["request"]) {
// Create new resource
}
else if ($_GET["request"]) {
// List existing resources
}
In both instances, the request parameter is sent to the same page, and different logic is run based on what the method is. But considering the same data is sent to the same page in both instances, the server wouldn't know which one of the two conditions to step into if the client doesn't explicitly specify the method.
In RESTful programming, both the client and server have been programmed to understand the request, but the client has no knowledge of the server itself. It is up to the server to process the request, based off of what the client asks it to do. And the client asks it to do different things by specifying the method.

Nginx Lua - rewrite url, forward original POST data/multipart form data

Nginx with its Lua extension makes it very easy to examine and manipulate a request prior to having it dispatched as appropriate. In my current project I am trapping all requests that arrive at a specified folder location, examining the request and then having it executed by an entirely different script. An outline of what I do:
/etc/nginx/sites-available/default Configuration
location /myfolder{
rewrite_by_lua_file "/path/to/rewrite.lua";
lua_need_request_body "on";
}
In rewrite.lua
ngx.req.set_header('special','my_special-header');
local data = ngx.req.get_body_data();
ngx.req.set_body_data(data);
and finally redirecting to another location:
ngx.req.set_uri("/myother/index.php",true);
With simple GET requests or POST requests with one or two items of attached POST data this works well. The issue I have been unable to resolve is this. Say for instance I am sending out multipart from data in my original request.
ngx.req.get_body_data()
actually gets the raw request body. If I forward this to /myother/index.php I can retrieve this as file_get_contents('php://input'). This is OK but not good enough. I don't want to have to deal with the raw input here. I would rather be able to work with standard PHP $_POST and $_FILES variables. However, those are empty and the their contents are present in the body as a text string.
Is there a way to tell Nginx that when I subject a user request to some treatment by Lua prior to forwarding it to another URL, it should just pass on the POST/PUT request fields as well as the whole of the original $_FILES array?

how do i resend a request after processing it inside my apigee endpoint

I have a endpoint called get user data which accepts a token
I need to read this token in my apigee and send it to tokenVarificationExtUrl
which gets back to me with
a) valid 200
b) userid attached with that token
now what i have to do is i need to read the response header and then conditionally check it for 200 success and then extract the userid from the response.
Once its extracted i need to attach it with another request; which i need to send to getUserData external url
which will get back to me with required user details.
I am successful of extracting data and doing conditional check. I am seeking help for
how do i send another request to getUserData external url.
You need to use a few policies in your proxy.
For example
For checking a header and throwing an error, you may want to use rasie fault policy conditionally
For making an API call to external end-point you can use service callout policy or a standard target
For exrtacting response data from json or xml payload you can use json path of xpath policies
and so on.
I suppose you may want to take a look at a few sample proxies with these functions to be able to design your own.
Check this link out. http://apigee.com/docs/content/using-sample-api-proxies

Should I be using a PUT or POST in this situation?

A server side service is populating the database. I send a http request from my application with some metadata information from the document and I want the server side service to generate a unique uuid for this document and populate the db with the doc uuid and metadata and send back the uuid to me. Should the client be executing a PUT request in this case or a POST. I only want one record of the document metadata and uuid generated for it.
PUT is generally used to overwrite and replace or create a resource.
I think that is what you should be using here. For example:
PUT /document/ HTTP/1.1
Host: example.com
And have it return a UUID and metadata for the document.
And quoting from another SO question:
I think one cannot stress enough the fact that PUT is idempotent: if
the network is botched and the client is not sure whether his request
made it through, it can just send it a second (or 100th) time, and it
is guaranteed by the HTTP spec that this has exactly the same effect
as sending once.

Resources