Lua scripting language: modify a response body in API gateway - lua

I would like to modify the response body returned by the backend.
As background I'll detail my specific problem (but I don't require a solution to the specific problem, just the method for manipulating a response body). I want to insert/add a key value pair to the response body based on the status code of the response and I want to transform snake_case keys into camelCase keys.
For example, given a response with
status code: 401
body: {'detail_message': 'user is not logged in'}
I want to transform it to a response with
status code: 401
body: {'success': False, 'detailMessage': 'user is not logged in'}
The rule for success would be True for anything below 400 and False for anything above or equal.
Lua scripting can be used in my API gateway which is Krakend
https://www.krakend.io/docs/endpoints/lua/
The documentation only includes examples for printing the response body and modifying headers but not for modifying the response body.
I have no experience with Lua and only need it for one task. I haven't been able to find online example of response body manipulation which I could play with.
What methods do I need in order to add a key value pair to a response body and to manipulate the keys in the response body?

Related

Charles, empty request body with non-empty response body

I used Charles to record a session and when I check one of the sessions, I found that there is no request body but I can see a response body, I am confused about this as how am I seeing a response without sending a request?
Also, I noticed that I can choose to see the request and response body on my phone's Charles, but on my desktop Charles, I can only see the tab called Content, I tried clicking on the request and response in the under the View tab, nothing happened as well. Does anyone know why?
Thanks!
I am confused about this as how am I seeing a response without sending a request?
A request consists of a few things:
Always: an HTTP method (GET, POST, or similar)
Always: a path (/document/123)
Optional: any number of HTTP headers (my-header: abc)
Optional: a request body
A response consists of:
Always: an HTTP status (404)
Always (in HTTP/1): an HTTP status message (Not Found)
Optional: any number of HTTP headers (my-header: abc)
Optional: a response body
In your case, you are sending a request, it's just that your request only contains a method, URL and headers, but no body. That's totally normal and this is very common for most HTTP requests.
The request and response body are totally independent: it's fine for neither to have a body, or for just one (either one) to have a body, or for both to have a body.
As an example, a GET request to https://google.com/search from a browser will include a method (GET) and a path (/search) and a selection of headers from the browser (such as a user-agent), but won't include any body, and the response will have a status (200) and message (OK), headers about the response data (e.g. content-length: ...) and the body will be the HTML for the google search page.

Does assigning a post request to a variable read all of its Reponse contents into memory?

Let's say we gave a generic POST request with Python's requests.
req = requests.post('http://someapi.someservice.com', files=files)
req will be a Response object. In my case, the .content of the response can be very, very large so I do not wish to read it all into memory. Luckily, requests provides an iterator .iter_content that allows iteration over the contents. My question is, though, does req contain all contents of the response already (and as such everything is already read into memory), or does calling .content and as such .iter_content initiate a download which really fetches the content? This is important, because if assigning the POST request to a variable already reads the Response's content into memory, then of course using .iter_content makes no difference.
You will need to set the stream parameter to True in your request in order to avoid downloading the entire content of the response into the response object:
req = requests.post('http://someapi.someservice.com', files=files, stream=True)
Excerpt from the documentation of Body Content Workflow:
By default, when you make a request, the body of the response is
downloaded immediately. You can override this behaviour and defer
downloading the response body until you access the Response.content
attribute with the stream parameter... You can further control the workflow by use of the Response.iter_content() and Response.iter_lines() methods.

AWS API Gateway issue for HTTP Method

I created an AWS API-gateway for an HTTP method PUT. When I do a test in API-gateway, that works fine, but when I call it from a REST client, I get 404 bad-request and missing authentication token errors. I didn't set any authorization to true or a required API key to true.
I passed these query parameters to a REST client:
auth_id : 8798iuyiu123123
time_stamp :1231231
test_json : [{"id"=>"1","value"=>"mount"},{"id"=>"2","value"=>"chart"}]
HEADER
content-type : application/json
When I change the test_json value to %5B%7B%22id%22:%221%22,%22value%22:%22test%22%7D,%7B%22id%22:%222%22,%22value%22:%2213+%D8%B4%D8%A7%D8%B1%D8%, then I get the response.
i am new to react, calling from react
Request.put('https://api-gateway.sqwdwed123.com/eretw/update-chart')
.set('Content-Type', 'application/json')
.query({ auth_id: localStorage.auth_id})
.query({ time_stamp:this.props.time_stamp})
.query({ test_json:JSON.stringify(newadd)})
should i pass this test_json through body?
Am I doing anything wrong?
This is usually related to requesting a URL that doesn't exist. Please make sure you're using the correct HTTP method and resource path to a valid resource (the sample invoke URL does not include any resource path). If this still doesn't work. Make sure you actually deployed your API.
The HTTP Response of Bad Request is because you have the Query Parameter that are not URL Encoded. There are 2 things that you can do now:
Pass the test_json as Query Param but making sure that they are URL Encoded. This will put a restriction on the size of the string and hence Not Recommended.
Pass the test_json as Request Body. (Recommended)

HTTP 100 Continue response CAN have a message body?

I am writing a HTTP Proxy in Delphi 6 using Synapse library.
I know that a regular response has the following syntax:
A Status-line
Zero or more header (General|Response|Entity) fields followed by CRLF
An empty line indicating the end of the header fields
Optionally a message-body
But 100 Continue is not a regular one, is just a inter-response that tells the client to continue and must be followed by a final regular response.
So, should I expect a body in a 100 Continue response?
No, 1xx status responses must not have a body. See http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-26.html#rfc.section.3.3.p.5:
"The presence of a message body in a response depends on both the request method to which it is responding and the response status code (Section 3.1.2). Responses to the HEAD request method (Section 4.3.2 of [Part2]) never include a message body because the associated response header fields (e.g., Transfer-Encoding, Content-Length, etc.), if present, indicate only what their values would have been if the request method had been GET (Section 4.3.1 of [Part2]). 2xx (Successful) responses to a CONNECT request method (Section 4.3.6 of [Part2]) switch to tunnel mode instead of having a message body. All 1xx (Informational), 204 (No Content), and 304 (Not Modified) responses do not include a message body. All other responses do include a message body, although the body might be of zero length."

RestResponse is null on POST request using RestSharp

I am making a POST request with RestSharp (on windows phone 7.1 client). I sent string to a service in a request body. Looks like the service is successfully called and it returns proper value (integer), however response object is null:
client.ExecuteAsync<T>(request, (response) => {
data = response.Data; // response is null in debugger
});
I cant understand why is that so.
<T> isn't a valid value for that call. I'm not sure that would even build there unless you've wrapped it in a generic method.
Also, is the response coming back as plain text? What's the Content-Type returned? Most likely, you should just use ExecuteAsync(request, callback) without the generic parameter and grab the data out of response.Content which is a string of the response body. response.Data is for the automatically deserialized XML or JSON (or custom) response if you use the generic method overload that specifies a type to deserialize to.
This seems to be an ongoing issue with RestSharp asynchronous calls - for HTTP transport errors ErrorException object is useless (returns null). Check the StatusCode property if it returns with anything but HttpStatusCode.OK. StatusDescription is not extremely useful either as it doesn't match complete status message from server response payload.

Resources