React Native - Interact with API - Special Characters Causing Issues - What's the best way to do this? - post

I cannot consistently successfully send form variables that may/may not include special characters e.g. ? & #
Depending on where I try to escape the chars I encounter different errors when reading the data server-side.
I am aware that an update is due for React Native 0.7 to include formdata but wondered if I could safely post objects without needing this.
Someone has already posted a similar issue but no example code was posted to illustrate the POST working:
How to post a form using fetch in react native?
I have tried - amongst other things :
fetch(APIURL, {
method: 'POST',
body: JSON.stringify({
object1: {
param1a: "value 1a",
param1b: "value 1b - with bad chars & # ?",
},
object2:
{
param2a: "value 2a",
param2b: 0,
}
})
})
but it groups the data into a single unnamed parameter (changing the API to accept this is not an option).
also this:
fetch(APIURL, {
method: 'GET',
accessPackage: JSON.stringify({
accessToken: "abc123",
tokenType: 2,
}),
taggData: JSON.stringify({
title: "test",
wishlistID: 0,
anotherVar: "anotherVal"
})
})
I wish to receive the data as two strings that can be parsed as json objects at the other end.
Looking at the the fetch repo https://github.com/github/fetch hasn't helped as this assumes the post with be a full JSON post (which it isn't) or uses FormData which isn't available to React Native yet.
Another solution may be to safely encode/serialise all of the data to URL parameters but this has also proven inconsistent so far especially with the # char.
What's the best way to do this?

"it groups the data into a single unnamed parameter (changing the API
to accept this is not an option)."
It would, because you've set the post body. This is how it's supposed to work.
I wish to receive the data as two strings that can be parsed as json objects at the other end.
You can do whatever you want, but there's no magic happening here. You will receive a single string, the string you set body to. Likewise, the post body can contain anything but shouldn't get confused with "special" characters. Most likely it is your server-side that is causing the problems.
If you want to use FormData then I think it'll be in v0.7.0 which should be out any day now, or you could probably just include the JS file in your own project. You can find it here. Usage examples are in the UIExplorer demo.

Related

How to make a POST request to Twilio to call a number with urequests

I have recently starting doing things with a raspberry pi zero W and wanted to be able to call a number from it.
Unfortunately it seems very hard to use the normal Twilio library because the pi uses MicroPython so I have to use the raw API.
I also gathered that the API uses the content type x-www-form-urlencoded which urequests seems to have a hard time interacting with.
This is my code so far
url = f"https://api.twilio.com/2010-04-01/Accounts/{TWILIO_USER}/Calls.json"
def call() -> None:
body = {"To": CALLING_NUMBER, "From": CALLER_NUMBER}
response = urequests.post(url, json=body, auth=(TWILIO_USER, TWILIO_KEY))
print("Status Code", response.status_code)
print("JSON Response ", response.json())
however I get the error
{'code': 21201, 'more_info': 'https://www.twilio.com/docs/errors/21201', 'message': "No 'To' number is specified", 'status': 400}
I have tried a ton of stuff like url encoding the body myself, using it as the parameter for data, json.dumpsing it, nothing seemed to work. Any help would be greatly appreciated.
Please remember I am limited by the picos standard libraries.
It seems I was close. All I had to do was copy paste urllib's urlencode and use it on body, then it ended up working.

Krakend: Use previous backend response data to populate post body using lua

I am new to Kraken but quite excited about it. What I am trying to do currently is to have two sequential backends where I would like to use parts of the response from the first backend to populate the body of the second request using Lua. the only issue I am having is to get a hold of the data that I can get via {resp0} if I use it outside the Lua scripts.
This is the part of the krakend.json where I would like to access the previous response:
"extra_config": {
"modifier/lua-backend": {
"sources": [ "/etc/krakend/config/lua/enrichRequestBody.lua" ],
"pre": " populate_request_body(request.load(), {resp0});",
"live": false
}
Any input or suggestions would be much appreciated!
Thanks
I have been trying finding {resp0} or the corresponding value from debugging but no luck. I haven't found any documentation or examples for this in the Kraken documentation

setting 'replace_original' to false while responding to Slack message action request doesn't work

Background:
I am using the python slack API (slackclient) to build an iterative sequence of data-gathering actions in ephemeral messages.
The core of this works fine. After processing the incoming request that contains the user's interaction with a set of message buttons (or menus), I respond immediately with a JSON body, as described in the "Responding right away" section of the official slack docs.
The problem:
Every response replaces the preceding message+attachments. In many cases, this is what I want, but there are situations where I want to add a response rather than replace the previous message.
Per the slack docs,setting replace_original to false should do just that. But the following code, snipped from my handling of a simple button click (for example), replaces the original button (and the text message to which it was attached):
r = {
'response_type': 'ephemeral',
'text': 'foo',
'replace_original': 'false'
}
log.debug("Returning: {}".format(json.dumps(r)))
resp = Response(response=json.dumps(r),
mimetype="application/json",
status=200)
return resp
I have tried this with and without the delete_original and response_type fields, with no change.
In short, it appears that in this case the replace_original field isn't doing anything at all; behavior is always as if it were set to 'true'.
I feel like I must be missing something here - any help is greatly appreciated.
Simple solution here: the slack API is expecting a boolean, not a string. So 'replace_original': 'false' in the above snippet ends up as {"response_type": "ephemeral", "text": "foo", "replace_original": "false"} after the json.dumps() call, which is invalid.
Instead, setting 'replace_original': False becomes {"response_type": "ephemeral", "text": "foo", "replace_original": false}, which then has the expected behavior

Implementing `startCursor` and `endCursor` in Relay

We have a graphql server not written in javascript, which we're trying to conform to the relay specification. startCursor and endCursor show up in a few examples but not in any official docs; based on my reading of https://github.com/facebook/relay/issues/372 those fields are basically deprecated, but they do show up in some code still. Do we have to implement them:
to be spec compliant?
to work with existing clients?
to be spec compliant?
As you point out, these fields don't appear in the spec, so they must not be required to conform to the spec. I conclude this because I think that's the only conclusion any serious authors of a spec should want you to draw from the absence of something from their spec.
to work with existing clients?
This, of course, is a different, more practical question :). The only client that I am aware of that uses the Connection spec is Relay, and Relay Modern requires these fields. Since these values are used by the PaginationContainer, the Relay Modern compiler requires them on any field marked with the #connection directive:
[END_CURSOR, HAS_NEXT_PAGE, HAS_PREV_PAGE, START_CURSOR].forEach(
fieldName => {
const pageInfoField = pageInfoType.getFields()[fieldName];
invariant(
pageInfoField &&
SchemaUtils.getNullableType(pageInfoField.type) instanceof
GraphQLScalarType,
'RelayConnectionTransform: Expected type `%s` to have an ' +
'%s field for which the type is an scalar in document `%s`.',
pageInfo.type,
fieldName,
definitionName,
);
}
);
I never remember which of endCursor and startCursor corresponds to which pagination direction. Since they are not documented in the spec, you can look to graphql-relay-js for this information:
startCursor: {
type: GraphQLString,
description: 'When paginating backwards, the cursor to continue.'
},
endCursor: {
type: GraphQLString,
description: 'When paginating forwards, the cursor to continue.'
},
No, they're not deprecated, and they do show up in the docs. What that issue says is that you don't have to implement them if you don't want to use them directly in your app, because Relay is going to query the cursor for each edge in a connection automatically, and will use that when making requests during pagination.

How do I inspect the full URL generated by HTTParty?

I want to look at the full URL the HTTParty gem has constructed from my parameters, either before or after it is submitted, it doesn’t matter.
I would also be happy grabbing this from the response object, but I can’t see a way to do that either.
(Bit of background)
I’m building a wrapper for an API using the HTTParty gem. It’s broadly working, but occasionally I get an unexpected response from the remote site, and I want to dig into why – is it something I’ve sent incorrectly? If so, what? Have I somehow malformed the request? Looking at the raw URL would be good for troubleshooting but I can’t see how.
For example:
HTTParty.get('http://example.com/resource', query: { foo: 'bar' })
Presumably generates:
http://example.com/resource?foo=bar
But how can I check this?
In one instance I did this:
HTTParty.get('http://example.com/resource', query: { id_numbers: [1, 2, 3] }
But it didn’t work. Through experimenting I was able to produce this which worked:
HTTParty.get('http://example.com/resource', query: { id_numbers: [1, 2, 3].join(',') }
So clearly HTTParty’s default approach to forming the query string didn’t align with the API designers’ preferred format. That’s fine, but it was awkward to figure out exactly what was needed.
You didn't pass the base URI in your example, so it wouldn't work.
Correcting that, you can get the entire URL like this:
res = HTTParty.get('http://example.com/resource', query: { foo: 'bar' })
res.request.last_uri.to_s
# => "http://example.com/resource?foo=bar"
Using a class:
class Example
include HTTParty
base_uri 'example.com'
def resource
self.class.get("/resource", query: { foo: 'bar' })
end
end
example = Example.new
res = example.resource
res.request.last_uri.to_s
# => "http://example.com/resource?foo=bar"
You can see all of the information of the requests HTTParty sends by first setting:
class Example
include HTTParty
debug_output STDOUT
end
Then it will print the request info, including URL, to the console.
As explained here, if you need to get the URL before making the request, you can do
HTTParty::Request.new(:get, '/my-resources/1', query: { thing: 3 }).uri.to_s

Resources