The Importance of GOOD Plumbing!
how do we manage the code/data?
OVERVIEW TONIGHT!
hello GitHub,
a little JSON gymnastics,
examples on BlueMix,
using Node.js and Express
- Pitches and followups
- Heather says GO FOR IT!!
- Hackvictoria?
- Bluemix day!
- will get to the "labs"
- SOSExample set off the fire alarms!
- Ain't no mountain high enough!
- what is next in the "experiment"?
Web
Server
RECAP!
development repo, webserver, client, google machines!!!
Web
Server
you &
me!
GitHub
git
Landscape
MAIN BRANCH of repo set up on Web Server...
Web
Server
you &
me!
GitHub
git
clients query search engine for content...
Web
Server
you &
me!
GitHub
git
many options returned (and rendered)!
Web
Server
you &
me!
GitHub
git
was there EVER a time before GOOGLE?
client accesses web server
Web
Server
you &
me!
GitHub
git
web server returns JS, CSS, HTML to client browser
Web
Server
you &
me!
GitHub
git
interactions with content generate data
for analytics!
Web
Server
you &
me!
GitHub
git
GitHub is free (typically open source...)
Hosting for Web Servers is *not* typically free!
What do you use?
GitHub
git
Web
Server
Open source projects? Let's all update the same (shared) file at the same time!!!!!
GitHub
-
code hosting platform
-
version control and collaboration
-
repositories, branches, commits, and pull requests
-
"repos" are shared in "branches"
-
shared changes are "commits" to a "branch"
-
"pull requests" are a workflow mechanisms to review changes before they are "committed"
GitHub?
-
A repo organizes files in a project
-
files (data and code!), images, folders...
-
README.md
-
markdown :)
-
we have a readme.md in our repo
-
want to you add a link to YOUR repo there!!!
-
-
-
- LET THE GAMES BEGIN! :)
Step 1: Create a Repo
- Branching allows us to have different versions of a file
-
master is the definitive branch
- other branches experiment with edits before committing them to master
- a branch off the master branch is a copy at that point in time.
- if changes are made to the master you could pull in those updates
- ready to share? "merge" with master!
- GO FOR IT!!!!!
Step 2: Branch!!!
-
your readme-edits branch, is a copy of master
-
make some edits!
-
saved changes are called commits
-
each commit has an associated commit message,
-
a description explaining why a particular change was made
-
-
messages capture the history of your changes
-
- GO FOR IT!!!
Step 3: Make & Commit Changes!!!
-
you have changes in a branch off of master
-
you can open a pull request
-
you’re proposing your changes and requesting review
-
pull in your contribution and merge with the branch
-
-
pull requests show diffs, or differences, of the content from both branches
-
- @mention system
- open pull requests in your own repository and merge them yourself!!!
- GO FOR IT!!!
Step 4: Open a Pull Request!!!
-
After review
-
add the changes to the master branch
-
DELETE the temporary branch!
-
- GO FOR IT!!!
NOOOOOOWWWWWWWWWW do the same for our shared README at:
https://github.com/ycoady/FortUVic2016
Step 5: MERGE!!!
Web Server FUN!!!
- public landmark app for art!
- "reverse engineering"
- uhoh... forgive me?!
- performed a search of all the art
- used "view source"
- got a lot of data!
var art =
[ {
"ArtworkId": 283,
"FullName": "Michael Abraham",
"Title": "The Reef Project",
"Municipality": "Victoria",
"ImageFilename": "victoria_3773_sm.jpg",
"Geometry": {
"Latitude": 48.4216395250979,
"Longitude": -123.383878470021
}
},
{
"ArtworkId": 299,
"FullName": "Robert Amos",
"Title": "Dragon Dance",
"Municipality": "Victoria",
"ImageFilename": "victoria_3841_sm.jpg",
"Geometry": {
"Latitude": 48.4297326859304,
"Longitude": -123.366763293295
}
]
JSON... really makes you think!
<body>
<h1> hi! </h1>
<div id="map" style="height: 600px"></div>
<script>
var map = L.map('map').setView([48.4209650, -123.37332], 13);
// this access token was borrowed from the Leaflet example! :)
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
maxZoom: 18,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
//a transient way of conveying info, with a "popup"
var popup = L.popup();
//this function is "called" when a user clicks on the map
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
//hey! someone clicked on the map!
map.on('click', onMapClick);
//this is just a little code segment to demonstrate how a loop works!
for (var i=0; i< art.length; i++) {
var marker = L.marker([art[i].Geometry.Latitude, art[i].Geometry.Longitude]).addTo(map);
var image = "http://www.landmarkspublicart.ca/Content/images/collection/" + art[i].ImageFilename;
marker.bindPopup(art[i].Title + " by " + art[i].FullName + "<img src = " + image + ">");
}
</script>
</body>
starting to put it all together...
starting to put it all together...
- SO FAR we have been able to wrap our brains around
- HTML DOM issues
- CSS working on the DOM
- JS performing actions for us
- and a LOT of things to help us build UIs!
- Skeleton
- Bootstrap...
- But we have been rendering this from LOCAL files
- stored on your laptop
- edited in Atom/Sublime
- rendered by your browser
- Let's rev up some server power on BlueMix!
- Could use others! Cloud9, Nitrous,io, AWS...
BUT FIRST...
- Make sure you can render what we have on your laptop
- go to our repo (FortUVic2016)
- open the ArtApp folder
- copy index.html and art.js to your laptop
- open index.html in your browser
- Isn't this enough?
- why do we need BlueMix?!
Node.js
- On the server, we need to be able to run some code
- Saw that there are a BUNCH of options
- the TODO list backends!
- We will go with Node.js (https://nodejs.org/en/)
- you use it to run JavaScript ON THE SERVER
- you can load in all kinds of other libraries
-
npm (node package manager https://www.npmjs.com/)
- note the acronym in the top left (reload the page)
- express (https://www.npmjs.com/package/express)
- fast, unopinionated, minimalist web framework...
-
npm (node package manager https://www.npmjs.com/)
moving to BlueMix
- Let's get BlueMix fired up!!!
- Node.js for your server container
- Lab 3 page 34 here:
- Make a simple change to index.html
- in the "public" subdirectory
- save your changes
- commit them to the repo
- NOTE: this is ON a BlueMix machine!!!!
- redeploy the app!
- note that it has a folder for IMAGES!!!!
DEPLOYING on BlueMix
- Use code from the ArtApp folder in our GitHub repo
- index.html
- replaces the guts of the existing file on BlueMix!
- there WILL be "errors" (read them!)
- remember to "save" the file!
- art.js
- add a new file!
- paste in guts from art.js in our repo
- remember to "save" the file
- index.html
- make sure these are in the "public" subdirectory of your Bluemix app!
- deploy the app from the workspace (next slide!)
DEPLOYING on BlueMix
View the Deployed app!
NOTE: use http and not https!
DATA
Full stack development: Front end and Back end
JavaScript all the way is very popular
MEAN Stack!
MongoDB is a document database each document is a data structure like this... similar to JSON! :)
{
"_id" : ObjectId("54c955492b7c8eb21818bd09"),
"address" : {
"street" : "2 Avenue",
"zipcode" : "10075",
"building" : "1480",
"coord" : [ -73.9557413, 40.7720266 ],
},
"borough" : "Manhattan",
"cuisine" : "Italian",
"grades" : [
{
"date" : ISODate("2014-10-01T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2014-01-16T00:00:00Z"),
"grade" : "B",
"score" : 17
}
],
"name" : "Vella",
"restaurant_id" : "41704620"
}
MongoDB is a document database
each document is a data structure like this...
similar to JSON! :)
{
"_id" : ObjectId("54c955492b7c8eb21818bd09"),
"address" : {
"street" : "2 Avenue",
"zipcode" : "10075",
"building" : "1480",
"coord" : [ -73.9557413, 40.7720266 ],
},
"borough" : "Manhattan",
"cuisine" : "Italian",
"grades" : [
{
"date" : ISODate("2014-10-01T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2014-01-16T00:00:00Z"),
"grade" : "B",
"score" : 17
}
],
"name" : "Vella",
"restaurant_id" : "41704620"
}
MongoDB is a document database
each document is a data structure like this...
similar to JSON! :)
_id is the primary key!
~
➜ ~ mongoimport --db test --collection restaurants --drop --file primer-dataset.json
connected to: 127.0.0.1
Mon Nov 2 00:49:01.901 dropping: test.restaurants
Mon Nov 2 00:49:03.078 check 9 25359
Mon Nov 2 00:49:03.084 imported 25359 objects
➜ ~
➜ ~ ps -aux | grep mongod
mongodb 53 0.2 4.1 553084 41804 ? Ssl Oct13 64:00 /usr/bin/mongod --config /etc/mongodb.conf
➜ ~
Getting Started with MongoDB (Node.js Edition)
mongodb has to be running...
can import a data set (drop means the old one is lost!)...
➜ ~ npm install mongodb
> kerberos@0.0.17 install /home/nitrous/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos
> (node-gyp rebuild) || (exit 0)
make: Entering directory `/home/nitrous/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/build'
CXX(target) Release/obj.target/kerberos/lib/kerberos.o
CXX(target) Release/obj.target/kerberos/lib/worker.o
CC(target) Release/obj.target/kerberos/lib/kerberosgss.o
../lib/kerberosgss.c:36:0: warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas]
#pragma clang diagnostic push
^
../lib/kerberosgss.c:37:0: warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas]
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
^
../lib/kerberosgss.c: In function ‘authenticate_gss_client_wrap’:
../lib/kerberosgss.c:362:19: warning: variable ‘server_conf_flags’ set but not used [-Wunused-but-set-variable]
char buf[4096], server_conf_flags;
^
../lib/kerberosgss.c: At top level:
../lib/kerberosgss.c:930:0: warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas]
#pragma clang diagnostic pop
^
CC(target) Release/obj.target/kerberos/lib/base64.o
CXX(target) Release/obj.target/kerberos/lib/kerberos_context.o
SOLINK_MODULE(target) Release/obj.target/kerberos.node
COPY Release/kerberos.node
make: Leaving directory `/home/nitrous/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/build'
mongodb@2.0.47 node_modules/mongodb
├── es6-promise@2.1.1
├── readable-stream@1.0.31 (isarray@0.0.1, inherits@2.0.1, string_decoder@0.10.31, core-util-is@1.0.1)
└── mongodb-core@1.2.20 (bson@0.4.19, kerberos@0.0.17)
➜ ~
Getting Started with Node.js
//this is the way we will communicate with the server
var http = require('http');
var dispatcher = require('httpdispatcher');
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var url = 'mongodb://0.0.0.0:27017/test';
var myText = ""; //building my own text here to ship to the client!
var findRestaurants = function(db, callback) {
var cursor = db.collection('restaurants').find( { "address.zipcode": "10075" } );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
myText = myText + "{\"name\": \"" + doc.name + "\" , \"cuisine\": \"" + doc.cuisine + "\", \"location\" : {\"lng\":" + doc.address.coord[0] + ", \"lat\":" + doc.address.coord[1] + "} },";
} else {
callback();
}
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findRestaurants(db, function() {
db.close();
});
});
//A sample GET request
dispatcher.onGet("/page1", function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader("Access-Control-Allow-Headers", 'Content-Type, X-Requested-With');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Content-Type', 'application/json');
res.write("{\"venues\" : [" + myText.substring(0, myText.length - 1) + "]}");
res.end();
});
//A sample POST request
dispatcher.onPost("/post1", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Got Post Data');
});
//We need a function which handles requests and send response
function handleRequest(request, response){
try {
console.log(request.url);
dispatcher.dispatch(request, response);
} catch(err) {
console.log(err);
}
}
//Create a server
var server = http.createServer(handleRequest).listen(3000, '0.0.0.0');
//Writes to the console that we are in business!
console.log('Server running at http://0.0.0.0:3000/');
We can start node and declare a MongoClient and connect to it!
BACK TO AN EXAMPLE!
-
HTTP has two operations we will use
-
Post
- sending data to the server
-
Get
- receiving data from the server
-
-
Take a quick look at our example code
- https://github.com/ycoady/FortUVic2016/blob/master/app.js
plumbing simply does NOT get better than this!!!
next for the "experiment"?
-
what do you need next?
Our Friend JSON
By Yvonne
Our Friend JSON
- 1,447