How to pass json data to aws lambda through API Gateway? - flutter

I am trying to send the JSON to AWS lambda to trigger lambda handler. I am using Flutter web for this project and my API end point is as below. Below is my code to hit AWS lambda endpoint.
Future<String> getResponse(jsonData) async {
var response =
await http.post(Uri.parse("https://7jua06h1r4.execute-api.ap-south-1.amazonaws.com/stage1/calc"), headers: header, body: jsonData);
if (response.statusCode == 200) {
print("Success");
} else {
print("Error");
}
}
When I try to hit and get response using postman, everything works fine and i get 200 status with response as well. But when i test it using my browser, it display the body is empty. Can you help me out please? How can i pass JSON data through API Gateway to lambda?
{"statusCode": 200, "body": {}}
When i try using Postman, it works as expected. you can see in the image below:
[1]: https://i.stack.imgur.com/Tczfw.png
My Lambda function:
import json
import boto3
def lambda_handler(event, context):
print(event['body'])
# TODO implement
return {
'statusCode': 200,
'body': event['body']
}
Here, i am not able to get the body i.e. JSON Data from my app.

I think that in your code need to replace it:
print(event['body'])
by
print(event.body.body)
Event is not the call body, body is inside of that object and you have an attribute called body.

When you tested it using your browser, did you pass body to the url? Assuming that you just typed your url
https://7jua06h1r4.execute-api.ap-south-1.amazonaws.com/stage1/calc
into the browser, you would have gotten an empty body in response, which is the correct behaviour.

Related

Relay Modern BadRequestError: Missing multipart field ‘operations’

I am trying to upload file to my server. using Altair i can do it without any error but when i use Relay.js for uploading it server throws following error.
BadRequestError: Missing multipart field ‘operations’ (https://github.com/jaydenseric/graphql-multipart-request-spec).
at Busboy.<anonymous> (/home/dotsinspace/Documents/dev/truck.pe__server/node_modules/.pnpm/graphql-upload#9.0.0_graphql#15.3.0/node_modules/graphql-upload/processRequest.js:362:11)
at Object.onceWrapper (events.js:420:28)
at Busboy.emit (events.js:326:22)
at Busboy.EventEmitter.emit (domain.js:486:12)
at Busboy.emit (/home/dotsinspace/Documents/dev/truck.pe__server/node_modules/.pnpm/busboy#0.3.1/node_modules/busboy/lib/main.js:37:33)
at /home/dotsinspace/Documents/dev/truck.pe__server/node_modules/.pnpm/busboy#0.3.1/node_modules/busboy/lib/types/multipart.js:52:13
at processTicksAndRejections (internal/process/task_queues.js:75:11)
Following are my graphql code and mutation which i am trying to commit.
#Graphql
graphql`
mutation AccountUploadMutation($profilePicture: Image!) {
AccountUpload(profilePicture: $profilePicture) {
message,
status
}
}
`
#Mutation
commitMutation(Environment, {
'mutation': AccountUploadMutation,
'variables': { 'profilePicture': v },
'uploadables': { 'file': v },
'onCompleted': (response, error) => Response({}, { response, error })
})
and I am totally confused about uploading part to..in uploadables you have to provide file..but my server looks for variable with profilePicture as image how can i deal with it.
It looks like you have an issue the multipart parsing configuration in your backend.
My guess is that the Relay Network is sending your GraphQL query in the mutlipart field "operation", but your backend is looking for the field "operations" (plural). To fix the error, confirm that your Network is sending the query in the operations field, or change your backend to read whatever field it's actually being sent on.
Another possibility is you're not sending your query in the multipart format at all. If you followed the Network documentation's example for sending your request, then you are just sending a JSON object, not a multipart form:
// Example from Relay docs. Sends a JSON object, not a multipart
// form as expected by your backend
function fetchQuery(
operation,
variables,
cacheConfig,
uploadables,
) {
return fetch('/graphql', {
method: 'POST',
headers: {
// Add authentication and other headers here
'content-type': 'application/json'
},
body: JSON.stringify({
query: operation.text, // GraphQL text from input
variables,
}),
}).then(response => {
return response.json();
});
}
// Create a network layer from the fetch function
const network = Network.create(fetchQuery);
If this is the case, write your fetchQuery function to fetch data using a multipart form. See this example: fetch post with multipart form data

flutter http request/response details including headers?

while http request details can easily be inspected in browser dev tools(for web app), I tried to explore, where I can find the same for requests sent in flutter App, but couldn't locate it.
like for example - I can see the actual response from api by print(response), but I am talking about complete request response including headers.
I am using VScode IDE for Flutter.
update:
I want to view the headers sent like response.header. reason for the same is like I am using flutter cahe manager and the issue I am facing is like I have set the -cache control max-age=1.
so the flutter should try to fetch the same every time I access the page, which it is doing, but it is serving the page from the cache and then fetching the request. so if there is any change is on server side, it doesn't reflect when first open the page, but shows the change on every second visit.
so what I want is like if the flutter gets 304 response from server, it will serve from the cache else it should serve from the fetched data. but it is not happening.
also the response.header is not showing response code like it is 200 or 304, so that flutter can fetch or serve from cache.
Actual code being used is like this:
Future<MyUserProfile> fetchMyUserProfile() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final userid = prefs.getString('user_id');
var userProfile = await DefaultCacheManager().getSingleFile("url");
final response = await userProfile.readAsString();
if (response != '') {
print(userProfile);
// If the server did return a 200 OK response,
// then parse the JSON.
return MyUserProfile.fromJson(json.decode(response));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load Profile');
}
}
Don't wanna be rude, but the information you are looking for is quite easy to find... That is if you look in the right place, like official documentation.
https://api.flutter.dev/flutter/dart-io/HttpResponse-class.html
HttpResponse class ... headers → HttpHeaders Returns the response
headers. [...] read-only
http.Response response = await http.get(url...
print(response.headers);
EDIT: Answering the sub-question that was added to the original question.
To check what the status code is you simply access it via response.statusCode
Example:
http.Response response = await http.get(url...
if (response.statusCode == 200) {
// do something
} else if (response.statusCode == 304) {
// do something else
} else {
// handle this
}

RedirectException: Redirect loop detected

I'm testing a request to get data from an URL using dio in my Dart code.
import 'package:dio/dio.dart';
class Api {
Dio dio = Dio();
var path = 'https://jsonplaceholder.typicode.com/users';
void getHttp() async {
try {
Response response = await dio.get(path);
print(response.data);
} catch (e) {
print(e);
}
}
}
In this case it brings the result correctly.
But, I actually need get data from this URL:
http://loterias.caixa.gov.br/wps/portal/loterias/landing/megasena/!ut/p/a1/04_Sj9CPykssy0xPLMnMz0vMAfGjzOLNDH0MPAzcDbwMPI0sDBxNXAOMwrzCjA0sjIEKIoEKnN0dPUzMfQwMDEwsjAw8XZw8XMwtfQ0MPM2I02-AAzgaENIfrh-FqsQ9wNnUwNHfxcnSwBgIDUyhCvA5EawAjxsKckMjDDI9FQE-F4ca/dl5/d5/L2dBISEvZ0FBIS9nQSEh/pw/Z7_HGK818G0KO6H80AU71KG7J0072/res/id=buscaResultado/c=cacheLevelPage/=/?timestampAjax=1588600763910
Using Postman I can access the data:
So, the problem is that, if I try to get data from that URL in my code, I get the following exception error:
I/flutter (23393): DioError [DioErrorType.DEFAULT]: RedirectException: Redirect loop detected
If this URL is redirecting, why is it working when using Postman? Anyway, how could I handle this redirected request in order to access data?
After a while, I noticed that the response to this request is coming as HTML and not as Json. So I needed to create a way to get DOM coming from the request, removing HTML tags and encoding string to Json.

flutter await GET response is not working

i have the follow function:
Future<Null> _loadORDER(String menssage) async {
var enZona =await ApiClient.zonaNum(menssage, apiKey);
print('enZona: $enZona');
if (enZona == 'true') {
_moveToNotification(context);
};
}
the print give me the follow message: "enZona: Instance of 'Response'"
if i test the response from postman of the api query is working normally and give me: true ,
then i hope that the print result will be : "enZona: true"
but i don't know how i do to wait the response of the ApiClient before continue with the conditional (if)
thanks for your help!
thanks i add the .body but i get the same response, the apiclient code is the follow:
final response = await http.get(baseUrl + '/shop/order/$message',
headers: {HttpHeaders.authorizationHeader: apiKey});
print("enZona: $response.body");
return response;
the print value for this is: enZona: Instance of 'Response'.body
You should do print("enZona: ${response.body}"); with the curly bracket, or you can assign response.body to some variable first.
final foo = response.body; print(foo);
If you go to the pub.dev documentation for the Response class, you will see that Response is more than the content of the response. It is a wrapper class that also includes information such as the statusCode of the response, the headers, etc.
When you saw the response in Postman, you only cared about the content of the response, that is, the body of the response. What you are looking for in your code is not the enZona instance of Response, but the body of the enZona response.
Therefore, you have to swap enZona by enZona.body when trying to access the contents of your response.

Getting partial api data from firebase functions- actions-on-google

When I try to access external API's for my google action from my webhook which is hosted on firebase functions, I am getting back only partial content. It stops getting the whole data provided by the api.
For example I tried getting data from wikipedia api using this code
var request = require('request');//required module
//inside the function
request({ method: 'GET',url:'https://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&explaintext=&exsectionformat=plain&redirects=&titles=11_September'},function (error, response, body)
{
if (!error && response.statusCode == 200)
{
console.log(body);
}
});
app.ask('data obtained');
Can anyone please help me out with this.
I am having a pay as you go firebase account that allows egress of data.
From just the code fragment, the problem is that you're replying to the user outside the callback from request(). This means that it is handled immediately and the function may end before the entire body has been received. Try something like this (I've also changed ask() to tell() since you're not prompting for another response here, and you shouldn't leave the microphone open.)
var request = require('request');//required module
//inside the function
request({ method: 'GET',url:'https://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&explaintext=&exsectionformat=plain&redirects=&titles=11_September'},function (error, response, body)
{
if (!error && response.statusCode == 200)
{
console.log(body);
app.tell('data obtained');
}
});