Using Express.JS to consume an API - javascript

var express = require('express');
var app = express();
var path = require('path');
var api = require('./api');
app.get('/', function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
})
app.listen(8080)
console.log('Server Running');
I know that we are requiring the express module. We are using the express function, we are requiring the module path and storing the reference in variable path and doing the same with api but beyond that I am a little lost. If I wanted to connect to twitter API how would I go about doing this? Can someone please explain the logic behind it so i can go learn this better and apply it by myself with different API's? I sincerely and greatly appreciate all of your help!

Express is a framework for organising your web application server. You open up certain API's routes to listen on the path and respond to the requests when necessary.
You can open API's only for internal use, i.e. calls from the browser running your app. Or you can expose your API to outer world (for example twitter API is doing that).
To connect to twitter API you need to make an outgoing request from your webserver. There are many ways to go about that, starting from native nodeJS package http https://nodejs.org/api/http.html to much more popular alternative request https://github.com/request/request
One thing to note here is that NodeJS web server are in general less restrictive than other language servers, especially when it comes to organising your app and code architecture. Hence more issues for beginners. Feel free to ask more questions.
Main purpose of app in
var app = express()
is to listen to routes (it is as well used to render pages, adding middleware etc.) and only that.
So assume u have a button on your UI which allows you to connect to twitter API. So on the click you make a GET request to your own server, to /api/twitter/connect .
On your server you listen on this path as follows:
var request = require('request'); //assuming you installed this module
app.get('/api/twitter/connect', function(req, res){
request(TWITTER_API_URL + API_KEYS, function(err, body){
res.json(body); //res is the response object, and it passes info back to client side
});
});

You can use "request" package to send requests. But in case of Cross-Origin-Request you must use "HTTPS" instead of "HTTP". You can configure Your request according to your request type like this..
//Load the request module
var request = require('request');
//Lets configure and request
request({
url: 'https://example.com/abc/demo', //URL to hit
qs: {from: 'example', time: +new Date()}, //Query string data
method: 'GET', // specify the request type
headers: { // speciyfy the headers
'Content-Type': 'MyContentType',
'Custom-Header': 'Custom Value'
},
body: 'Hello Hello! String body!' //Set the body as a string
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Besides this there are others way to do the same. And for twitter you can also checkout the module called "twitter"

Related

Accessing the database API directly with client-side JS

I need to build a simple web front-end which will be mostly used to plot some data fetched from a database. The database (namely, InfluxDB) exposes a HTML API which I could just conveniently call directly from my Javascript front-end. I'm putting login service in front of it (AWS Cognito).
However, once a user logs in, they can easily discover my API endpoints in the client-side code, and therefore make arbitrary queries and possibly abuse it or just steal all my data. How can I avoid it? Is it possible to somehow make the API accessible only to the app's front-end? If not, what is the best practice I should follow here?
I'd suggest maybe creating a Node.js based webservice that would wrap your REST API. Using the Express module it's only a few lines to put together a simple REST service and call out to other APIs.
const request = require('request');
const express = require('express');
const app = express();
app.get("/test", function(req, res, next){
res.status(200).send('Hello World');
});
app.get("/testapi", function(req, res, next){
// Read from another API and return result...
var options = {
url: "https://httpbin.org/ip",
method: "get"
};
request(options, function (error, response, body) {
if (error) {
console.error('error:', error);
res.status(500).send(error.message);
} else {
res.status(200).send(body);
}
});
});
let port = process.env.PORT || 3000;
app.listen(port);
console.log(`Express listening on ${port}..`);
If your InfluxDB is also running on EC2, the fastest and safest approach would be to only allow your web application access to the influxdb instance by limiting it in the security group.
Image that your webapp is running on the default VPC with CIDR 172.31.0.0/16 and that influxdb is running on port 8086. Then simply create a security group with an INBOUND rule that port 8086 can only be reached from inside your AWS account (So IP 172.31.0.0/16) and attach it to your Influx EC2 instance. make sure other inbound rules allowing access to 0.0.0.0/0 are removed.

Calling a Node.js server with Vue.js

I have a simple Node.js server up and running. This is the code:
var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('Hello World!');
res.end();
})
server.listen(8090);
server.once('listening', function() {
console.log('Hello World server listening on port %d', 8090);
});
I can call this server using curl from the command line:
$curl localhost:8090
However, when I try to call it from a Vue application, I get an error. I have a Vue application running on localhost:8080, and I want to call my localhost:8090 server. My main.js Vue file is this:
import Vue from 'vue'
import resources from 'vue-resource'
Vue.use(resources)
import App from './components/App.vue'
import style from './styles/main.scss'
/**
* Root Vue instance
* #param {[element]} el: 'body' [Adds to the html body]
* #param {[component]} components: {app: App} [Renders ./component/App]
*/
new Vue({
el: 'body',
components: {
app: App
}
})
And this is the App component:
<template>
<h1>{{ msg }}</h1>
<input v-model="msg">
<button v-on:click="get">Call Server</button>
</template>
<script>
export default {
data: function() {
return {
msg: 'Hello World!'
}
},
methods: {
get: function() {
// GET request
this.$http({
url: 'localhost:8090',
method: 'GET'
}).then(function(response) {
console.log('ok');
}, function(response) {
console.log('failed');
});
}
}
}
</script>
When I click the button I get this error:
XMLHttpRequest cannot load localhost:8090. Cross origin requests are
only supported for protocol schemes: http, data, chrome,
chrome-extension, https, chrome-extension-resource.
When I try to call another server, like google.com, I get this error:
build.js:19188 GET http://localhost:8080/google.com 404 (Not Found)
So it seems like Vue is putting the localhost:8080 in front of the call, and maybe this is where my problem lies? Making server calls is completely new to me, I'm just playing around with Vue and want to learn Node.js while I do so.
This basically has nothing to do with Node or Vue and everything to do with how security in the browser is implemented. CORS is not a workaround. Read up on CORS to see why it is needed. This question of mine, which is quite similar to yours, has some good info in the answers sections as well. To be able to call an API without using CORS it needs to run on the same host, port and protocol, otherwise it will be blocked by your browser.
Years ago, before the advent of CORS, you needed to use JSONP to achieve the same. You can of course have a look at it to see how this works, but nowadays there is very little need for that technique as we have proper cross-domain support in the form of CORS.
Regarding your question in one of the comment sections on "How do people call API's when working with Vue.js?", they do one of the following:
Run the API on another server (such as api.mydomain.com), but set the CORS headers on the response.
As above, but the client and server wraps responses using the JSONP method mentioned above.
Run the API on the same server as the one serving pages. This means api calls will be done against an endpoint such as localhost:8080/api
Twist on #3: just proxy calls coming in on the server to another server. Meaning you can have your api server running elsewhere, but your main server that is accepting calls on /api will just send these requests on the the next server after stripping off the /api prefix. Usually, people either setup an Apache or Nginx instance in front of your app server and do the actual proxying on that, but you can also do it in your app server, using something like node-proxy.
You can probably read this through the lines already, but save yourself some trouble (and time) and just use CORS :) #trquoccuong has the details on doing this in his answer.
CORS problems, you can use cors node module or add request header
if use Express
res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
if use http module
res.setHeader

Create/configure node.js dispatcher/proxy

I'm working on javascript Single Page Application with Aurelia framework and using simple fake backend(express.js) for prototyping purposes.
Backend runs on localhost:8081 and client app on localhost:9000
There are some Cross Domain issues because these are different ports, and adding cross origin headers to the backend seems cumbersome to me.
What i want is simple dispatcher/proxy that would run on, say, localhost:3000 and redirect incoming calls in this manner (localhost:3000/app => localhost:9000) (localhost:3000/api => localhost:8081) Thus eliminating cross domain issues.
I'm looking for really simple solution, maybe there is some node.js app that suited just for such cases.
If you are using Express, you can add this routes to your app.
You need to install the module 'request' for this example
// At the top
var request = require('request');
And then:
//APP
app.use('/app', function (req, res) { request('http://localhost:9000' + req.originalUrl).pipe(res); });
//API
app.use('/api', function (req, res) { request('http://localhost:8081' + req.originalUrl).pipe(res); });

Node.js HTTP Request to send OSC message

I am new to Node.js and am wondering if anyone has an idea on how I'd go about making a program that sends an OSC message when someone makes an HTTP request to my server?
I have a simple program running right now that when you run it it sends an OSC message, how might I expand it so this message gets sent anytime a certain HTTP request is made?
var osc = require('node-osc');
var client = new osc.Client('127.0.0.1', 3333);
client.send('/1', 1);
Thanks
To receive HTTP requests, you need an HTTP server. Node has a built-in HTTP server. To handle simple routing, I usually go straight for Express which sets up a nice middleware stack and some other helpful bits as you build out your application. From the documentation:
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
Now, what I would do is set up a specific endpoint for OSC messages:
app.all('/osc', functin (req, res) {
oscClient.send('/1', 1);
}
You can add parameters and what not if you want Express to handle that for you in the URL, or you can get at the query string or POST data directly from the req object.

How can a Node.js library register for HTTP requests on a particular URL path?

I am writing a library for a web service in Node.js. My library needs to handle all HTTP requests with a particular URL prefix (Eg, /_docs/*).
I want people to be able to use my library without changing much of their code.
The API should look something like this:
server = http.createServer(function(req, res) { ... });
...
myLibrary.listen(server, '_docs/');
or
server = new http.Server();
myLibrary.listen(server, '_docs/');
server.on('request', function(req, res) { ... });
If I merely register another event handler on the server object, the user's http request handler will be called on all HTTP requests as well. My code will race with the user's 404 handler.
Socket.io has a similar problem, and they solve it by making their .listen() function move all existing http request handlers into a private array. When HTTP requests come in, if their code doesn't handle the URL it calls the listeners in the array. However, as far as I can tell this wouldn't work in the second example I've shown above.
Whats the best way to make this work?
What about Connect? Router middleware provides rich Sinatra / Express-like routing.
Example
connect.router(function(app){
app.get('/user/:id', function(req, res, next){
// populates req.params.id
});
app.put('/user/:id', function(req, res, next){
// populates req.params.id
});
})
For advanced use look at http://expressjs.com/guide.html#routing.

Categories