How to add an additional endpoint to the AWS Amplify Express Server? - javascript

I've generated an REST express server with Amplify.
I tried adding to more endpoints to it:
// using serverless express
app.post('/myendpoint', function(req, res) {
console.log('body: ', req.body)
res.json(req.body)
});
// using serverless express
app.get('/myendpoint', function(req, res) {
res.json({success: 'get call to my endpoint succeed!', url: req.url});
});
After running amplify push I don't see these endpoints in the console, and I can't make requests to them via amplify.
The endpoints that were generated as part of the initial configuration work.
What is the correct way to add more REST endpoints? I have a feeling that I'm missing some additional configuration step.

After deploy the API and function, to add additional path you should use "amplify update api"

As Kevin Le stated running "amplify update api" will allow you to add another "root" path such as "/items" or "/customers", but I have been running into problems adding nested paths such as "/customer/addAddress" after the initial api creation.
What I have tried:
I can add them during the initial creation of the API, but not during an update
I can change the cloud formation template to include them in the API gateway, but any calls to the nested path are picked up by the root paths proxy.
I can add them in the express lambda function ( defeats the purpose of API Gateway )
They need to add a few enhancements to amplify rest API so we can take advantage of the API Gateway. It's not truly serverless until we can separate functions for GET, POST, PUT, etc.
UPDATE: I wanted to follow up after futher investigation. A solution I found is to remove the "root" path's {proxy} endpoint in the cloud formation file for the API gateway. The file should be located at: "project root"/amplify/backend/api/"api name"/"api name"-cloudformation-template.json. Then remove the path located at Resources->"api name"->Properties->Body->paths->"api name"/{proxy+}.
FURTHER INVESTIGATION: I have not tried this yet, but the order of the path's in the cloud formation file might have an affect on how the requests are processed, so if you move the "root" proxy to the last path, you might not have to remove it. Also thanks to Piotr for fixing my poor grammar!

You can run "amplify update api"
then choose to add a new endpoint
and choose assign new(old) lambda function for this endpoint

Related

Upload JSON File to my server with vue and node js

I'm new to node js and vue development and I want to create a process where I can create and upload a JSON file to my server when the user saves data in a form. This process should be done in the background. Later I want to read and update that file from the server when the user changed something.
So my first idea was to use fs.writeFile() this doesn't work very well and I think this only works for local stuff is that correct?
var fs = require('fs')
export default {
methods:{
send(){
fs.writeFile("/test.json","Hello World!",function(err){
if(err){
throw err;
}
});
}
}
}
Furthermore it looks like fs.writeFile doens't work with vue because it throws this error:
TypeError: fs.writeFile is not a function at VueComponent
So my second idea was to use express js with the app.post('/api/apps',...) and app.get() method. Here I have no idea how to implement that into the vue framework because I have to call the api like mydomain.com/api/apps but this doesn't work too.
So what is the best way to create, read, upload, delte files into a specific folder on my server? And how it works with vue? I tend to express js.
I'm using vue cli :)
Thanks in advance :)
EDIT
Now what I do is:
I created a new folder in my vue project root and named it "backend". In this folder I created a file named index.js and put this code
app.post('/appjson',(req,res) => {
fs.writeFile("/appjson/myJson.json",req.body,function(err){
//handle error
});
});
on the client side I put this code
axios.post('myDomain.com/appjson', {
JSONdata: myJSONdata,
})
My project looks like:
So when I build I get the dist folder and this I can upload on my server and it works fine. But I can't do the call to my backend? Whats wrong do I call the wrong link? Or how can I access my backend? Is the project struture correct or do I need to add the backend to a specific folder?
Vue is client side, your code is trying to write something to the filesystem of the user thats using your website. what you want to do is send this data to your NodeJS server, this requires using a package like Axios to send data to and from the server without refreshing the page. Axios is pretty straight forward to use, what you need will look similar to the function below.
saveJSON (myJSONData) {
const url = myNodeJSURL/savescene
return axios.post(url, {
JSONdata: myJSONdata,
})
Read some tutorials on ExpressJS, It's a pretty painless framework to use. You'll get the data stored in the body of the HTTP request and then you can use fs.writeFile to save data to the local filesystem of your server. Let me know if you need more help.
EDIT:
Your front end needs to be access a domain or IP address associated with your back end in order to communicate with it. Add the snippet below to your ExpressJS application and then when you run the server any requests to localhost:3000 will be handled by your app. You'll also have to update the URL in your Axios call.
app.listen(3000, function () {
console.log('my server is listening on port 3000!')
})
this setup only works for testing purposes because client and server will have to be on the same machine for localhost to mean the same to both. If you want this project to be public then you need to get your own domain for your site and host the ExpressJS application through there. Google compute makes this pretty easy to do, I'd look into that if I were you.

Google Cloud Storage change notifications with Node.js

I have Firebase storage bucket and I would like to use Node.js Google-cloud notification API in order to listen to changes in the storage.
What I have so far:
const gcloud = require('google-cloud');
const storage = gcloud.storage({
projectId: 'projectId',
credentials: serviceAccount
});
const storageBucket = storage.bucket('bucketId');
Now from what I understand I have to create a channel in order to listen to storage changes.
So I have:
const storageBucketNotificationChannel = storage.channel('channelId', 'resourceId');
This is the threshold where the docs stop being clear, as I can't figure out what channelId a resourceId stand for.
Nor do I understand how to declare listening to channel changes itself. Are there any lifecycle-type methods to do so?
Can I do something like?
storageBucketNotificationChannel.onMessage(message => { ... })
Based on the existing documentation of the Google Cloud Node.js Client and the feedback from this Github issue, there is presently no way for the node client to create a channel or subscribe to object change notifications.
One of the reasons being that the machine using the client may not necessarily be the machine on which the application runs, and thus a security risk. One can still however, subscribe to object change notifications for a given bucket and have notifications received a Node.js GAE application.
Using Objects: watchAll JSON API
When using gsutil to subscribe, gsutil sends a POST request to https://www.googleapis.com/storage/v1/b/bucket/o/watch where bucket is the name of the bucket to be watched. This is essentially a wrapper around the JSON API Objects: watchAll. Once a desired application/endpoint has been authorized as described in Notification Authorization, one can send the appropriate POST request to said API and provide the desired endpoint URL in address. For instance, address could be https://my-node-app.example.com/change.
The Node/Express application service would then need to listen to POST requests to path /change for notifications resembling this. The application would then act upon that data accordingly. Note, the application should respond to the request as described in Reliable Delivery for Cloud Storage to retry if it failed or stop retrying if it succeeded.

NodeJS & Express connect External API - Any useful tool, to manage the data received?

I'm connecting to an external API on my backend.
Data flow : External API -> My backend -> Client side
I know that exists modules like request or http that helps this process.
But, When I receive the data from External API, I need to modify it and add some information. After I'll send this "modified data" to the Client side.
I am searching a tool similar to BackBone Collections on the backend to help me. BB Collections have awesome functions like fetch/sort/each.
Every time I google only I found frameworks like BackBone on the client side not on the server side.
Edit 1
Tool would have to help me iterating over array (received from external API) or accessing to item with specific attr given.
Solved
After studying both options (Lodash and Unirest), finally I decided to use Lodash combined with request.
Try lodash to handle arrays in server side.
var unirest = require('unirest');
app.get('/api', function(req, res){
unirest.get('http://localhost:3000/getlist')
.header('Accept', 'application/json')
.end(function (response) {
response.body.forEach(function(item){
//handle item
});
res.send();
});
});
Maybe Unirest?

Listen for a webhook server side using meteor

I've set up a meteor app using iron-router and I want the app to listen to a webhook from another service (basically I'm building an API for other services to use)
So for example, when an external website calls myapp.meteor.com/webhook I want to catch that specific link and parameters and do stuff with the data.
Update: Thanks to a comment I found this: https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#server-routing
Router.route('/webhooks', { where: 'server' })
.post(function () {
console.log(this);
this.response.end('Caught you\n');
//this.response.status(200).json({text:"Todo added"});
});
I added the above in the /server folder as there is no need to for the front-end server to worry about this like mentioned in the comment. But when I load this using postman POST request, it just returns my HTML for not found. Any ideas?
Thanks in advance for your help.
UPDATE
I tried what #David said and still I get the template loaded and nothing in the console. Any idea what I'm doing wrong?
Your server route will only run if no client routes also match. I suspect you have a catch-all route which is executing on the client and preventing the server route from running. One solution is to define all of the routes in a common folder like /lib so that you can properly order them. Your routes file could look something like:
client route 1
client route 2
server route 1
server route 2
catch-all (not found) route

Where to place remote hooks (beforeRemote, afterRemote)code in yo loopback generated code

I'm using loopback generator to generate models and rest APIs service. Now I wanted to modify a rest api such that everytime the api is called, some spcific logging/actions are taken.
I've come to know that by using remote hooks(beforeRemote, afterRemote), we can specify actions to be taken for different remote method calls. But what I don't know is that where to place the code of remote hooks. In which file this code will go when the project has been created using 'yo loopback'.
You would add code to the files under /common/models.
If you are using a Person model. You would add the following code in /common/models/person.js:
If you want to protect the REST API from a non logged in user or anonymous user you should use ACL. Have a look here:
Define access control from the intermediate tutorial
Authentication, authorization, and permissions
The REST API will respond with codes if someone unauthorized tries to get access (depending on what you define), for example 401. Then in the app if you receive that code, you should redirect to the login.
Now, every time you create a new model with slc loopback:model, it will generate 2 files in the common/models folder. One is a .js and the ohter a .json. You have to add the code in the .js file for the remote hooks.
Have a look to this link that explains how to add remote methods.

Categories