Skip to content

Instantly share code, notes, and snippets.

@megamaddu
Last active August 4, 2017 09:22
Show Gist options
  • Save megamaddu/c6ae50e4a165bf2d4248 to your computer and use it in GitHub Desktop.
Save megamaddu/c6ae50e4a165bf2d4248 to your computer and use it in GitHub Desktop.

Nodejs!

What's node?

Node is a program (usually run from the command line) which executes JavaScript, and comes with a built-in library for writing network and filesystem code. Node is built on V8, the same JavaScript VM used in the Chrome browser. Instead of being wrapped with a GUI and web browser features like the DOM, node wraps V8 to expose lower-level operating system APIs. Some modules that come with node include: http, fs (filesystem), crypto (cryptography), and lots more.

What's a module?

Modules are chunks of code you can 'require' and then use. Today we'll use the http module, like so:

var http = require('http')

require is a function built into node. It takes a string module name and returns that module.

You can make your own modules!

// my-module.js

module.exports = 'hey!'
// app.js

var myModule = require('./my-module')

console.log(myModule)

Notice the require string is now a relative path, and that we've emitted the .js. It's optional for the js extension.

Modules are great for breaking your code down into smaller pieces that are easier to think about.

http module

This is what we'll be using today, but first...

The network stack

  • HTTP
  • TLS (optional)
  • TCP
  • IP
  • Ethernet
  • Physical card

Try this:

ping www.google.com

You should seen an IP address in parenthesis that will be used for subsequent pings. Where'd that address come from? This is the IP layer, specifically a DNS (Domain Name Service) lookup.

Try pinging again using that IP address instead. The results should be the same.

Now try this:

telnet www.google.com 80

This is the next layer up: TCP. Telnet is a tool for working with TCP connections. The command above says to open a TCP connection with www.google.com on port 80, which is the default for non-secure web traffic.

HTTP is the next layer after TCP (in a non-secure connection), so let's try some!

(still inside the telnet prompt)
GET / HTTP/1.1

Did you get all the HTML back? We can do everything above in one step with curl:

curl www.google.com

curl is an HTTP tool.

Ok, back to node!

Make a new directory to work in, then create a server.js file in that directory. Edit that file so it looks like this:

var http = require('http')

Lecture prep notes

Discuss: Front-end vs. back-end. Explain what we’re going to cover today using this graph. Explain that we’ve covered foundations and front-end frameworks, and now we’re going to the other side of the web request: the server side.

Discuss: Basics of HTTP. (HTTP is just text strings going back and forth) Talk about the innards of HTTP requests: Discuss: Go over basic HTTP status codes (200, 404, 500, etc.) (reference here) Discuss: Go over headers, what they are, what they’re used for [Dicsuss]: Bodies of requests/responses. (You can have JSON, HTML, etc) Discuss: HTTP “action verbs”, GET, POST, etc.

[Practice]: Use telnet to talk to Google. (What is telnet?) telnet google.com 80 GET / What happens when you use PUT/DELETE (or some other verb you make up) as opposed to GET?

Discuss: We use HTTP verbs (see above) to communicate with web servers. Discuss: REST and CRUD - REST Constraints - Client-Server separation - Stateless - no client info stored on server - Cacheable - Layered system - there are tools used to connect a client and server - Code on demand (optional) - Uniform interface - clients and servers can grow independently [Demonstrate]: Example URL/Verb structure of a REST API GET /users/ PUT /users/ POST /users DELETE /users/

What is cURL? (Its use in the real-world, documentation, etc.) [Practice]: use curl to make GET requests to google. curl google.com curl http://smurfs.devmounta.in/smurfs/ curl -X POST http://smurfs.devmounta.in/smurfs/ (will show JSON error) curl -X POST -d “name=[some name]” http://smurfs.devmounta.in/smurfs/
curl http://smurfs.devmounta.in/smurfs/[id] (use the ID of the smurf you just created) curl -X PUT -d “name=Dumb” http://smurfs.devmounta.in/smurfs/[id]

We discussed Node.js briefly a couple weeks ago. (They should all have Node, NPM installed) What is Non-blocking IO? When PHP hits a line that requires an IO operation, like a database read/write, PHP basically pauses execution at that line and hands over control to the database software to execute the command. Once the operation on the database completes, the control is given back to PHP and executes the commands after that line. This is blocking, because the database operation "blocks" PHP execution until it completes. With the same situation, NodeJS does this by asynchronously calling the IO operation. This means that while the operation is ongoing on the database, NodeJS proceeds in doing other stuff like cater the next request. When the IO operation completes, NodeJS runs the handler that was set to handle the data when the operation completes. Great for RESTful APIs

[Demonstrate]: Installing and setting up Node.js (Everyone should already have Node.js ready to go)

[Practice]: Make a simple Server (server.js) that responds to any GET request with

Hello world.

var onRequest = function(req, res) {
	res.statusCode = 200;

       res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Content-Type', 'text/html');

	res.end('<h1>Hello world</h1>');
}
var http = require('http');
var server = http.createServer();
server.on('request', onRequest)
server.listen(12200);

Run using node server.js .

Prove that this is a real “server” by having them access the server via their phones (http://:). Pretty cool, right?

[Practice]: Change the content-type to JSON (have them look up the appropriate header value, "What header would we need to use for JSON?") and return some JSON.

function onRequest(req, res) {
	res.statusCode = 200;

res.setHeader('Content-Type', 'application/json');

	res.end(JSON.stringify({message: 'Hello World'}));
}
var http = require('http');
var server = http.createServer();
server.on('request', onRequest)
server.listen(12200);

Now make a really simple html page that tries to access the endpoint they just created. Make sure they understand that we're using jQuery/$.get as just a really simple way to make a web request. We've done this with Angular services up to this point.

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script>
      $(function() {
        //$http in Angular. $.get in jQuery. Make the distinction
        $.get('http://localhost:12200')
      });
    </script>
  </head>
</html>

Open the file using http-server. Open the network tab and examine the request and response.

Discuss: What if we were trying to access data from a domain we weren't hosting on? In other words, what if we had a site on http://example.com but we needed to get data from another domain of ours, http://awesome.com? Because of Same-origin policy implemented by browsers, we can't do this. By default, browsers will only allow Javascript to manipulate or access API resources that originate from the same domain. There are times where we do want communication to happen across domains, which is why we can implement special HTTP headers that define a cross-origin policy and thus allow us to access data across separate domains.

If we want to have data accessible from other domains, we'd need to add the appropriate ‘Access-Control-Allow-Origin’ header to fix.

function handleRequest(req, res) {
// Everything is 200 OK
res.statusCode = 200;

// We’re sending JSON
res.setHeader('Content-Type', 'application/json');

// Allow data access from other domains
res.setHeader('Access-Control-Allow-Origin', '*');

// Don’t allow script execution from other domains
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
res.setHeader('Content-Security-Policy', "default-src 'self'");

var result = {message: 'Hello World'};
var jsonResult = JSON.stringify(result);
	res.end(result);
}
var http = require('http');
var server = http.createServer();
server.on('request', handleRequest)
server.listen(12200);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment