Enter the World of Node.js

My very very first goal was to write a simple web server that responds with “Hello World” for every request.

So I create a javascript file named app.js:

1
2
3
4
5
6
7
8
9
10
11
12
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(3100);
console.log('Server running on port 3100.');
 
process.on('SIGINT', function() {
  console.log("\nGracefully shutting down from SIGINT (Ctrl-C)");
  // some other closing procedures go here
  process.exit();
});
% node app.js

Debugging from Vagrant

with a pleasant graphical interface: Node Inspector (“npm install -g node-inspector”) is a debugger interface for node.js using the WebKit Developer Tools.

For debugging from host machine I have to setup port forwarding in the Vagrantfile, e.g. port 4466:

config.vm.network "forwarded_port", guest: 4466, host: 4466 # node-inspector

Then spin up the vagrant box and ssh to it:

% vagrant up
% vagrant ssh

cd to the project dir and start the node-inspector

% node-inspector --web-port 4466

The above command return the following: “Visit http://127.0.0.1:4466/debug?port=5858 to start debugging.”

Start the node application with the debug flag in a new terminal window.

% node --debug app.js

Ready to debug via the V8 JavaScript Engine which is used in the Chrome and Chromium browsers.

A better-written article can be found on sitepoint.
http://www.sitepoint.com/enter-world-node-js/

Installing the latest NodeJS & MongoDB Combo

NodeJS

Requirements

These are needed for building and running.

sudo apt-get install build-essential python

Install

https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager.

OR

Build & Install

download the latest NodeJS source code.

wget -N http://nodejs.org/dist/node-latest.tar.gz

Decompress and enter the directory.

tar -xvzf node-latest.tar.gz
cd node-v*

Configure the make file for my machine then build and install as a root user.

./configure
make
sudo make install

Test to make sure it was installed.

node -v
npm version

MongoDB

I should follow the instructions on the official MongoDB manual.

MongoDB Driver

see: http://docs.mongodb.org/ecosystem/drivers/.

What things do I need for a RESTful hypermedia architecture (RMM Level 3)

For my work I need to find out what is necessary for a modern REST-API. In theory, I want to get a global view about the glory of REST “Richardson Maturity Model“.

First, I want to thank Matthew Weier O’Phinney for the documentation about his PhlyRestfully module for the Zend Framework 2. PhlyRestfully implements RESTful JSON APIs in Hypermedia Application Language (HAL). He also explain things under the hood.

It should be forgiven, that I will use many words from his documentation for a overview in this lazy article. :-)

HAL Primer
HAL, short for “Hypermedia Application Language”, is an open specification describing a generic structure for RESTful resources.
- expose resources
- via HTTP, using HTTP verbs to manipulate them
- and provide canonical links to themselves, as well as link to other, related resources

Hypermedia Type
HAL presents two hypermedia types, one for XML and one for JSON. Typically, the type is only relevant for resources returned by the API, as relational links are not usually submitted when creating, updating, or deleting resources. The generic mediatype that HAL defines for JSON APIs is “application/hal+json”.

Resources
For JSON resources, the minimum I must do is provide a “_links” property containing a “self” relational link. As an example:

{
    "_links": {
        "self": {
            "href": "http://example.org/api/users/1"
        }
    }
    "id": "1",
    "name": "Homer Simpson"
}

Interacting with HAL
a request, using the Accept header with a value of “application/json” or “application/hal+json” (the latter really isn’t necessary, though).
If POST’ing, PUT’ting, PATCH’ing, or ‘DELETE’ing a resource, you will usually use a Content-Type header of either “application/json”, or some vendor-specific mediatype you define for your API; this mediatype would be used to describe the particular structure of your resources without any HAL “_links”. Any “_embedded” resources will typically be described as properties of the resource, and point to the mediatype relevant to the embedded resource. The API will respond with a mediatype of “application/hal+json”.

API-Problem
How do I reporting errors?
REST advocates indicate that HTTP response status codes should be used, but little has been done to standardize on the response format.
This mediatype, “application/api-problem+json” is via the IETF, and actually also includes an XML variant.
- problemType: a URL to a document describing the error condition (required)
- title: a brief title for the error condition (required)
- httpStatus: the HTTP status code for the current request (optional)
- detail: error details specific to this request (optional)
- problemInstance: a URL to the specific problem occurrence (e.g., to a log message) (optional)

HTTP/1.1 500 Internal Error
Content-Type: application/api-problem+json
 
{
    "problemType": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
    "title": "Internal Server Error",
    "detail": "Status failed validation",
    "httpStatus": 500
}

Whitelisting HTTP Methods
should I provide with the via HTTP method, OPTIONS, and a related HTTP response header, Allow. Calls to OPTIONS are non-cacheable, and may provide a response body if desired. They should emit an Allow header, however, detailing which HTTP request methods are allowed on the current URI.

OPTIONS /api/users
Host: example.org

with it’s response:

HTTP/1.1 200 OK
Allow: GET, POST

Content Negotiation
Should a client inform the server what media types it understands. More precisely, the client provides an Accept HTTP header that lists acceptable media types and associated quality factors. It can choose the best representation of a resource. see: http://en.wikipedia.org/wiki/Content_negotiation

the accept definition in our request should be: “*/json”

Service Versioning via Content Negotiation
Inevitably there will come a time when an API requires a change to its returned or expected representation that will cause consumers to break and that breaking change must be avoided. Versioning the API is the way to avoid breaking clients and consumers.

# Request
GET http://example.com/api/users/12345
Accept: application/json; version=1
 
# Response
HTTP/1.1 200 OK
Content-Type: application/json; version=1
{"id":"12345", "name":"Homer Simpson"}

Metadata Mapping
Do I need a low-level, configurable mechanism that ensure:
- resources have the correct “self” relational link
- resources are extracted to a JSON representation correctly
- that embedded resources are rendered as embedded HAL resources

The metadata map maps a class to a set of “rules” that define whether the class represents a resource or collection, the information necessary to generate a “self” relational link etc.

CRUD, Verbs, and Actions

GET /users              index   display a list of all users
GET /users/new          new     return an HTML form for creating a new user
POST /users             create  create a new user
GET /users/:id          show    display a specific user
GET /users/:id/edit     edit    return an HTML form for editing a user
PATCH/PUT /users/:id    update  update a specific user
DELETE /users/:id       destroy delete a specific user

resource names are in plural

OPTIONAL: ETags
There two uses for ETags (Entity Tags):
- Conditional GET (the so-called “cacheing mechanism”)
- Concurrency Control (resolves “Lost Update Problem”)

Libraries
HAL
API-Problem
Backbone.HAL
ZF2.PhlyRestfully

« Older Entries