Must provide Source with graphql API call in AWS amplify - amazon-web-services

I have got an error during a graphql API call in AWS amplify
I import the queries like (just like in the documentation with *):
import * as queries from '../graphql/queries';
This is my API request where I receive the error (Must provide Source):
const data = await API.graphql(graphqlOperation(queries.nearbyZVL, {filter: filter}));
And in the same file another API request like below is working correctly:
const result = await API.graphql(graphqlOperation(queries.getProfile, { id: cognitoUserId }));
The nearbyZVL is a custom query and resolver in AWS appsync. In the appsync console the query is working fine!
Some help is appreciated! :)

Not sure why it is not generated in codegen - to create custom resolvers, did you manually edit on appsync console, or adding files under /amplify/backend? For the latter, it should codegen. If you did the former, consider do the latter.
In your case, you can simply do below:
const GetNearbyZVL = `...` // the query that works in appsync console
const data = await API.graphql(graphqlOperation(GetNearbyZVL, {filter: filter}));

Related

503 error when fetching an internal NextJS api with query parameters on AWS Amplify

I am trying to fetch data from a JSON file through NextJS internal API on the client side. But it is always throwing 503 error:
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
I tried to use the GET method with query params in the URL, but it didn't work, then I try the POST method with the query in the body(just to test out), but it also didn't work either.
Here is the code:
const response = await fetch(`/api/search?q=${query}`, {
method: "GET",
headers: {
'Content-Type': 'application/json',
},
})
const res = await response.json()
I have another component that sends some user inputs to save in my DB, and it is working perfectly. (I am really confused why one works but not other given both are equivalent request)
Also, the same app deployed on Vercel is working perfectly. So I think the issue is with Amplify.
Anyone had similar issues with the Next app on Amplify? please help.
most likely you are sending a GET request but you have something in the body. e.g. form-data. this is example in postman.

Appery.io aws S3 integration

Looking for help on how to have a appery.io ionic 5 app upload images, files, videos etc. to aws S3. I am using aws DynamoDB thru API Express successfully and can get a presigned S3 URL thru API Express as well. My problem is using the presigned URL to upload a image/file. Tried fetch, httpClient etc. Some Guidence would be greatly appreciated.
Thank you
To work with binary data in API Express you can do the following:
Create new service of Custom REST API type
In START node select POST method and Binary for request body
With that you should be able to select Binary request as parameter value in SQL node
The second part of the question is how can you get the binary data if you have fileUrl.
Import API Express service created on a previous step into your project with Create New > API Express service
On Code tab create a variable named buffer of type Any
On Data tab add datasource for the imported API Express service. In Before send mapping connect buffer with body.data
Drop the button on Screen1
Add event with TypeScript code to it:
fetch(fileUrl).then(res => res.arrayBuffer()).then(arrayBuffer => {
this.buffer = arrayBuffer;
this.Apperyio.execDataService(this, "myAexService");
});

In Powershell, how do I create a PatchOperation that adds AWS IAM authorization to an existing API Gateway Endpoint?

I want to run a PowerShell script in an AWS Lambda that will update an API Gateway endpoint to require IAM authorization. The API Gateway is auto generated from the swagger generated by another application (.NET Core C#).
I've completed some code that is getting me close, but I am getting an error that I'm not sure how to resolve. Here's what I have so far:
$patchOperation = New-Object -Type Amazon.APIGateway.Model.PatchOperation
$patchOperation.Path = '/ResourceMethods/PUT/AuthorizationType'
$patchOperation.Value = 'AWS_IAM'
$patchOperation.Op = 'add'
Update-AGResource -RestApiId $ApiId -ResourceId $resource.Id -PatchOperation $patchOperation
The error I'm getting is:
Invalid patch path '/ResourceMethods/GET/AuthorizationType' specified for op 'add'. Must be one of: []
The desired result is that the API Gateway endpoint specified by the IDs will be updated to require IAM authorization when using the verb GET. Ideally, the operation will be idempotent.
I was able to figure this out by using the network tab in my browser debugger to see the values sent to the server. The structure for the PatchOperation object I want is:
{"op":"replace","path":"/authorizationType","value":"AWS_IAM"}
I also determined this was not a great approach. We are generating the OpenAPI doc with SwaggerGen. We can use an OperationFilter to add the authentication to the endpoint like so:
public class ApiGatewayIntegrationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
operation.Extensions.Add("x-amazon-apigateway-auth", new ApiGatewayAuth
{
Type = "AWS_IAM"
});
}
}

Fail to enable CORS for API Gateway functions

I get
While attempting to enable CORS on API Gateway, why is that and how do I resolve this? These functions are deployed using AWS SAM. But I notice if I create my own APIs via AWS Console this happens too
The errors looks like:
invalid model name specified application/json=Empty
invalid response status code specified
I found I seem to need to add an "Empty" response model myself?
Now, I get
Add Access-Control-Allow-Origin Integration Response Header Mapping to POST method (invalid response status code specified)
How do I resolve this?
Firstly please select your root resource and select "Enable CORS". It will enable CORS to all methods. Ideally it should work. If in case it doesn't work Please add an empty json in the response as I have marked in the screenshot attached. I believe you don't have any default response header added in your OPTIONS method response (in Method Response ). Please refer screenshot
Create a new model from the left menu that you will call Empty and it works
I had a CORS problem with API Gateway + Lambda and the above answers did not help me but I figured out I needed to add some headers information to my response code in my API.
I needed to add the res.statusCodeand the two headers.
// GET
// get all myModel
app.get('/models/', (req, res) => {
const query = 'SELECT * FROM MyTable'
pool.query(query, (err, results, fields) => {
//...
const models = [...results]
const response = {
data: models,
message: 'All models successfully retrieved.',
}
//****** needed to add the next 3 lines
res.statusCode = 200;
res.setHeader('content-type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', '*');
res.send(response)
})
})
2020 answer: Nowadays, there's an option called HTTP API when creating an API in the dashboard. For this type, I've found the CORS configuration to be much easier. If you have a working API of this type, you just have to click "CORS" under "Develop" in the sidebar, and then add '*' under Access-Control-Allow-Origin.

Amazon S3 upload via JS: safe credentials

I'm trying to upload a video file to AWS S3 bucket without the user logging via google or anything (the user shouldn't have to do anything!) This page suggests that there are 3 options:
Using Amazon Cognito to authenticate users
Using web identity federation to authenticate users
Hard-coded in your application
3rd option works for me, but is not acceptable on production environment.
1st and 2nd option both require a lot of hassling not just for developers but for a user also if I understood correctly.
// Not safe, but working!
/*AWS.config.update({
accessKeyId: "myaccesskey",
secretAccessKey: "mysecretkey",
"region": "eu-central-1"
});*/
AWS.config.region = 'eu-central-1';
var s3 = new AWS.S3();
var params = {
Bucket: 'mybucketname',
Key: file.name,
Body: file
};
s3.putObject(params, function (err, res) {
if (err) {
console.log("Error uploading data: ", err);
} else {
console.log("Successfully uploaded data to myBucket/myKey");
}
});
I also tried loading credentials from json file but this also did not work.
AWS.config.loadFromPath('./config.json');
The error with this approach is:
aws-sdk-2.4.13.min.js?ver=0.0.1:5 Uncaught TypeError:
n.FileSystemCredentials is not a constructor
Will I need to use server scripts to upload the file? (create a proxy between my JS and S3)
Any help appreciated.
Thanks.
EDIT: someone suggested I followed http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html to make a safe requests via browser/js. Anyone tried it yet perhaps? Any JS examples anywhere?
Posting the answer (if it can be called so) as I noticed this was not answered: I actually used server side AWS libraries to make this work and the variables were safely stored as ENV variables. Also, I changed some functionality so I did not need to use JS to make this work.
So did not need to fiddle with 1st and 2nd option mentioned above.
If someone finds a JS solution for the above two methods I'll gladly accept their answer.