Executive Summary
This project is similar to Project-B (in that you will build a number of WEB services) except you will use NodeJS instead of Tomcat. This allows us to augment our TCP (Project-A) and Java (Project-B) backend with JavaScript services. You will use all these services in the next two projects to build a shopping-cart web application.The Environment
It is highly recommended that you use your red
account for this project
rather than your own computer. Since we will be using CLI (the command-line interface)
for this project, it is very easy to work remotely by ssh'ing to your account. To that
end, use your favorite non-GUI editor (such as nano, vim, or emacs) to edit your
source files. Once you are fully comfortable with creating Node.js services, you can
download the needed packages to your own machine and deploy on your AWS EC2 instance.
To create a Node.js project named projC, issue this command:
nodeGo projCYou will be prompted to confirm several options. Accept all their defaults by pressing ENTER and then typing "yes" at the end of the prompts. This will create a directory named projC directly under your home directory and set it up. Your "servlet" file should be created in it under the name
index.js
. Once created,
you run it using command:node index.js
Since index.js
is intended to instantiate a service, the above command
will block until you press ^C. Any logging on standard output (done in JavaScript
via the console.log
function) will appear under the above command
along with any exceptions thrown.
The Services
This Project asks that you develop and test three micro services with the following functional specifications:- GeoNode: This service is the Node counterpart of the Java GeoWeb service
of Project-B and the Stateful service of Project-A.
It receives two URL-encoded parameters
lat
andlon
containing the GPS coordinates of a place on Earth. If this is the first time this client has made such a request then the return would be thetext/plain
payload "RECEIVED". If not, then the return would be thetext/plain
payload "The distance from (lat1,lon1) to (lat2,lon2) is XXX", where XXX is the geodesic distance between the previous place (sent in the last request) and the current one (sent in this request). This can continue (to a 3rd, 4th, ... places) as long as the requests are made within the same session. All computations must be made by delegating to the TCPGeo
service of Project-A; i.e. this Node service does not do any math. - Catalog: This service receives one URL parameter
id
containing an integer and returns the id and name of the row corresponding to that id in theCategory
table of the Models_R_US.db database (which resides in~/4413/pkg/sqlite
). The return should be mimed as "application/json" in the response's content type. If theid
parameter is missing then the return should be an array of json objects for all rows in the table. Here is an example of the response when the request parameterid
is 2:[{"id":2,"name":"Classic Cars"}]
- Trip: This service receives two URL parameters
from
andto
containing the start and end addresses of a trip. It returns the optimal distance (in km) and time (in minutes) between them given the current traffic conditions. To get this information, connect to your GCP (Google Cloud Platform) account athttps://maps.googleapis.com/maps/api/distancematrix/json
and pass the following parameters:origins
containing thefrom
address,destinations
containing theto
address,key
containing your API key, anddeparture_time=now
to factor in the current traffic conditions.
Service Implementation
Use the design patterns, methodologies, and hints demonstrated in lecture in order to speed up development and learn best-practice approaches.- Develop all 3 services in one project, but each in its own middleware (i.e.
app.use
) function . The route (URL mapping) should be the same as the service name. - Use the following fragment as a template for your
index.js
:const port = 8000; const home = '/cs/home/...'; const DB_PATH = home + '/4413/pkg/sqlite/Models_R_US.db'; const net = require('net'); const https = require('https'); const express = require('express'); const session = require('express-session'); var app = express(); var sqlite3 = require('sqlite3').verbose(); var db = new sqlite3.Database(DB_PATH); app.enable('trust proxy'); // Testing middleware for url mapping route: http://host:port/Test?x=123 app.use('/Test', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/html'}); res.write("Hello ... this is EECS4413/Fall19 Tester! "); res.end("You sent me: " + req.query.x); }); /* app.use(session( { secret: "mine", proxy: true, resave: true, saveUninitialized: true })); app.use('/GeoNode', function(req, res) { ... }); app.use('/Catalog', function(req, res) { ... }); app.use('/Trip', function(req, res) { ... }); */ // --------------------------------------SERVER var server = app.listen(port, function() { var host = server.address().address; var port = server.address().port; console.log('Listening at http://%s:%d', host, port); });
Testing & Deployment
Test your services through a browser usinghttp://host:port?qs
,
where qs
is the query string. Use localhost with port 8000 when
testing on a workstation. To deploy on red, use red.eecs.yorku.ca
for the host and set port = 0
in index.js
so that
the O/S will give you the next free port.
Persist Your Work
Simply upload yourindex.js
to the
course cloud so you can use it during tests.
(You can also upload it to your github, Google Drive, DropBox, S3, or some other cloud service).