Create a Restful API using Mongoose, Joi and Hapi.js

Create a Restful API using Mongoose, Joi and Hapi.js

Create a Restful API using Mongoose, Joi and Hapi.js: Mongoose connects Node and MongoDB, Joi validates the data and schema, and Hapi provides the webapp framework

Create a Restful API using Mongoose, Joi and Hapi.js
Mongoose connects Node and MongoDB, Joi validates the data and schema, and Hapi provides the webapp framework

What the difference between REST API and RESTful API?

What the difference between REST API and RESTful API?

Representational state transfer (REST) is a style of software architecture. As described in a dissertation by Roy Fielding, REST is an "architectural style" that basically exploits the existing technology and protocols of the Web. RESTful is typically used to refer to web services implementing such an architecture.

The short answer is that REST stands for Representational State Transfer. It’s an architectural pattern for creating web services. A RESTful service is one that implements that pattern.

The long answer starts with “sort of” and “it depends” and continues with more complete definitions.

Defining REST

Let’s start by defining what REST is and is not. For some, REST means a server that exchanges JSON documents with a client over HTTP. Not only is that not a complete definition, but it’s also not always true. The REST specification doesn’t require HTTP or JSON. (The spec doesn’t mention JSON or XML at all.)

The Origins of REST

Roy Fielding introduced the REST architectural pattern in a dissertation he wrote in 2000. The paper defines a means for clients and servers to exchange application data. A key feature is that the client doesn’t need to know anything about the application in advance. The link is to chapter five of his paper. While the entire dissertation describes the hows and whys of REST, that chapter defines the architectural pattern.

Fielding doesn’t mandate specific requirements. Instead, he defines REST regarding constraints and architectural elements.

REST’s Architectural Constraints

Here is a summary of the constraints.

  • Client-server – REST applications have a server that manages application data and state. The server communicates with a client that handles the user interactions. A clear separation of concerns divides the two components. This means you can update and improve them in independent tracks.
  • Stateless – servers don’t maintain any client state. Clients manage their application state. Their requests to servers contain all the information required to process them.
  • Cacheable – servers must mark their responses as cacheable or not. So, infrastructures and clients can cache them when possible to improve performance. They can dispose of non-cacheable Information, so no client uses stale data.
  • Uniform interface – this constraint is REST’s most well known feature or rule, depending on who you ask. Fielding says “The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components.” REST services provide data as resources, with a consistent namespace. We’ll cover this in detail below.
  • Layered system – components in the system cannot “see” beyond their layer. So, you can easily add load-balancers and proxies to improve security or performance.

A RESTful service is more than a web server that exchanges JSON, or any other, documents. These constraints work together to create a very specific type of application.

Applying the Constraints

First, the client-server, layered systems and stateless constraints combine to form an application with solid boundaries and clear separations between concerns. Data moves from the server to the client upon request. The client displays or manipulates it. If the state changes, the client sends it back to the server for storage. Fielding specifically contrasts REST with architectures that use distributed objects to hide data from other components. In REST, the client and server share knowledge about data and state. The architecture doesn’t conceal data, it only hides implementations.

The cacheable and uniform state constraints go one step further. Application data is available to clients in a clear and consistent interface and cached when possible.

So, that’s the technical definition of REST. What does it look like in the real world?

RPC Over HTTP vs. RESTful

Often when someone says that a service “isn’t REST,” they’re looking at the URIs or how the service uses HTTP verbs. They’re referring to REST’s presentation of data as a uniform set of resources.

This distinction is sometimes framed as a difference between remote procedures calls (RPC) and REST. Imagine a web service for listing, adding, and removing, items from an e-commerce inventory.

In one version, there’s a single URL that we query with HTTP GETs or POSTs.  You interact with the service by POSTing a document, setting the contents to reflect what you want to do.

Add new items with a POST with a NewItem:

POST /inventory HTTP/1.1
 
{
    "NewItem": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

Query for items with a POST and an ItemRequest:

POST /inventory HTTP/1.1
 
{
    "ItemRequest": {
          "id": "1001"
      }
}

Some implementations accept a request for a new item with a get, too.

POST /inventory?id=1001 HTTP/1.1

We also change or delete items with a POST and an ItemDelete or ItemUpdate.

POST /inventory HTTP/1.1
 
{
    "ItemDelete": {
          "id": "1001"
      }
}

This isn’t REST. We’re not exchanging the state of resources. We’re calling a function with arguments that happen to be in a JSON document or URL arguments.

A RESTful service has a URI for each item in the inventory.

So, adding a new item would look like the example above.

POST /item HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

But the similarities end there. Retrieving an item is always a GET:

GET /item/1001 HTTP/1.1   

Deleting is a DELETE:

DELETE /item/1001 HTTP/1.1  

Modifying an item is a PUT:

POST /inventory HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "7.99",
          "id": "1001"
      }
}    

The difference is important. In REST, operations that use distinct HTTP actions. These verbs correspond directly to the activity on the data. GET, POST, PUT, DELETE and PATCH all have specific contracts. Most well-designed REST APIs also return specific HTTP codes, depending on the result of the request.

The critical point is that the URIs operate on the data, not on remote methods.

But there’s another reason why the resource model is essential.

REST vs RESTful and the Richardson Maturity Model

When you model your URIs after resources and use HTTP verbs you make your API predictable. Once developers know how you defined your resources, they can almost predict what the API looks like. Here again, the emphasis is on understanding the data, not the operations.

But even if you can’t make the API entirely predictable, you can document any REST service with hypertext. So, each item returned in the inventory app would contain links for deleting, modifying, or setting the inventory level of the resource. Fielding says that before a service is RESTful, it must provide hypertext media as part of the API.

Many sites don’t meet this requirement but are still called REST. Fact is, many sites break the rules in one way or another. So many that Leonard Richardson created a model breaks down REST into levels of compliance

We’ve already covered the source levels:

  • 0 – exporting an API over HTTP with methods called with arguments
  • 1 – Exporting resources instead of methods
  • 2 – Proper use of HTTP verbs
  • 3 – Exporting hypertext with objects that make all or part of the API discoverable.

Richardson’s model is his own, and it doesn’t map directly into Fielding’s spec. Since Fielding requires level three, he would say that most apps aren’t REST anyway.

The point is many services that we colloquially refer to as REST, technically aren’t.

REST vs RESTful: Does It Matter?

So, does the REST vs. RESTful comparison matter? Probably not. How well your architecture complies with an arbitrary standard isn’t as important with how well it suits your needs and can grow with your business.

The REST architectural pattern has many advantages. Fielding designed it for the web and, 18 years later, most of the constraints he had in mind are still with us. In 2000 we didn’t have Android or the iPhone. IE5 had 50% of the browser market share. It’s biggest rival was Firefox. But Fielding recognized what online applications needed and how web clients would evolve from HTML display engines into complete applications. The tools we use today have grown to suit REST, not the other way around.

Thank you for reading. Hope this tutorial will help you!

Creating RESTful APIs with NodeJS and MongoDB Tutorial

Creating RESTful APIs with NodeJS and MongoDB Tutorial

Welcome to this tutorial about RESTful API using Node.js (Express.js) and MongoDB (mongoose)! We are going to learn how to install and use each component individually and then proceed to create a RESTful API.

Welcome to this tutorial about RESTful API using Node.js (Express.js) and MongoDB (mongoose)! We are going to learn how to install and use each component individually and then proceed to create a RESTful API.

MEAN Stack tutorial series:

  1. AngularJS tutorial for beginners (Part I)
  2. Creating RESTful APIs with NodeJS and MongoDB Tutorial (Part II) 👈 you are here
  3. MEAN Stack Tutorial: MongoDB, ExpressJS, AngularJS and NodeJS (Part III)
1. What is a RESTful API?

REST stands for Representational State Transfer. It is an architecture that allows client-server communication through a uniform interface. REST is stateless, cachable and has property called idempotence. It means that the side effect of identical requests have the same side-effect as a single request.

HTTP RESTful API’s are compose of:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images

Here is a summary what we want to implement:

NOTE for this tutorial:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
2. Installing the MEAN Stack Backend

In this section, we are going to install the backend components of the MEAN stack: MongoDB, NodeJS and ExpressJS. If you already are familiar with them, then jump to wiring the stack. Otherwise, enjoy the ride!

2.1 Installing MongoDB

MongoDB is a document-oriented NoSQL database (Big Data ready). It stores data in JSON-like format and allows users to perform SQL-like queries against it.

You can install MongoDB following the instructions here.

If you have a Mac and brew it’s just:

	

brew install mongodb && mongod

In Ubuntu:

sudo apt-get -y install mongodb

After you have them installed, check version as follows:

# Mac
mongod --version
# => db version v2.6.4
# => 2014-10-01T19:07:26.649-0400 git version: nogitversion

# Ubuntu
mongod --version
# => db version v2.0.4, pdfile version 4.5
# => Wed Oct  1 23:06:54 git version: nogitversion

2.2 Installing NodeJS

The Node official definition is:

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.> Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
In short, NodeJS allows you to run Javascript outside the browser, in this case, on the web server. NPM allows you to install/publish node packages with ease.

To install it, you can go to the NodeJS Website.

Since Node versions changes very often. You can use the NVM (Node Version Manager) on Ubuntu and Mac with:

# download NPM
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.4/install.sh | bash

# load NPM
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm

# Install latest stable version
nvm install stable

Check out https://github.com/creationix/nvm for more details.

Also, on Mac and brew you can do:

brew install nodejs

After you got it installed, check node version and npm (node package manager) version:

node -v
# => v6.2.2

npm -v
# => 3.9.5

2.3 nstalling ExpressJS

ExpressJS is a web application framework that runs on NodeJS. It allows you to build web applications and API endpoints. (more details on this later).

We are going to create a project folder first, and then add express as a dependency. Let’s use NPM init command to get us started.

# create project folder
mkdir todo-app

# move to the folder and initialize the project
cd todo-app
npm init .  # press enter multiple times to accept all defaults

# install express v4.14 and save it as dependency
npm install [email protected] --save

Notice that after the last command, express should be added to package.json with the version 4.14.x.

3. Using MongoDB with Mongoose

Mongoose is an NPM package that allows you to interact with MongoDB. You can install it as follows:

npm install [email protected] --save

If you followed the previous steps, you should have all you need to complete this tutorial. We are going to build an API that allow users to CRUD (Create-Read-Update-Delete) Todo tasks from database.

3.1 Mongoose CRUD

CRUD == Create-Read-Update-Delete

We are going to create, read, update and delete data from MongoDB using Mongoose/Node. First, you need to have mongodb up and running:

# run mongo daemon
mongod

Keep mongo running in a terminal window and while in the folder todoApp type node to enter the node CLI. Then:

// Load mongoose package
var mongoose = require('mongoose');

// Connect to MongoDB and create/use database called todoAppTest
mongoose.connect('mongodb://localhost/todoAppTest');

// Create a schema
var TodoSchema = new mongoose.Schema({
  name: String,
  completed: Boolean,
  note: String,
  updated_at: { type: Date, default: Date.now },
});

// Create a model based on the schema
var Todo = mongoose.model('Todo', TodoSchema);

Great! Now, let’s test that we can save and edit data.

3.2 Mongoose Create
// Create a todo in memory
var todo = new Todo({name: 'Master NodeJS', completed: false, note: 'Getting there...'});

// Save it to database
todo.save(function(err){
  if(err)
    console.log(err);
  else
    console.log(todo);
});

If you take a look to Mongo you will notice that we just created an entry. You can easily visualize data using Robomongo:

You can also build the object and save it in one step using create:

Todo.create({name: 'Create something with Mongoose', completed: true, note: 'this is one'}, function(err, todo){
  if(err) console.log(err);
  else console.log(todo);
});

3.3 Mongoose Read and Query

So far we have been able to save data, now we are going explore how to query the information. There are multiple options for reading/querying data:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images

Some examples:

// Find all data in the Todo collection
Todo.find(function (err, todos) {
  if (err) return console.error(err);
  console.log(todos)
});

The result is something like this:

[ { _id: 57a6116427f107adef36c2f2,
    name: 'Master NodeJS',
    completed: false,
    note: 'Getting there...',
    __v: 0,
    updated_at: 2016-08-06T16:33:40.606Z },
  { _id: 57a6142127f107adef36c2f3,
    name: 'Create something with Mongoose',
    completed: true,
    note: 'this is one',
    __v: 0,
    updated_at: 2016-08-06T16:45:21.143Z } ]

You can also add queries

// callback function to avoid duplicating it all over
var callback = function (err, data) {
  if (err) { return console.error(err); }
  else { console.log(data); }
}

// Get ONLY completed tasks
Todo.find({completed: true }, callback);

// Get all tasks ending with `JS`
Todo.find({name: /JS$/ }, callback);

You can chain multiple queries, e.g.:

var oneYearAgo = new Date();
oneYearAgo.setYear(oneYearAgo.getFullYear() - 1);

// Get all tasks staring with `Master`, completed
Todo.find({name: /^Master/, completed: true }, callback);

// Get all tasks staring with `Master`, not completed and created from year ago to now...
Todo.find({name: /^Master/, completed: false }).where('updated_at').gt(oneYearAgo).exec(callback);

MongoDB query language is very powerful. We can combine regular expressions, date comparison and more!

3.4 Mongoose Update

Moving on, we are now going to explore how to update data.

Each model has an update method which accepts multiple updates (for batch updates, because it doesn’t return an array with data).

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images

Alternatively, the method findOneAndUpdate could be used to update just one and return an object.

// Model.update(conditions, update, [options], [callback])
// update `multi`ple tasks from complete false to true

Todo.update({ name: /master/i }, { completed: true }, { multi: true }, callback);

//Model.findOneAndUpdate([conditions], [update], [options], [callback])
Todo.findOneAndUpdate({name: /JS$/ }, {completed: false}, callback);

As you might noticed the batch updates (multi: true) doesn’t show the data, rather shows the number of fields that were modified.

{ ok: 1, nModified: 1, n: 1 }

Here is what they mean:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
3.5 Mongoose Delete

update and remove mongoose API are identical, the only difference it is that no elements are returned. Try it on your own ;)

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
4. ExpressJS and Middlewares

ExpressJS is a complete web framework solution. It has HTML template solutions (jade, ejs, handlebars, hogan.js) and CSS precompilers (less, stylus, compass). Through middlewares layers, it handles: cookies, sessions, caching, CSRF, compression and many more.

Middlewares are pluggable processors that runs on each request made to the server. You can have any number of middlewares that will process the request one by one in a serial fashion. Some middlewares might alter the request input. Others, might create log outputs, add data and pass it to the next() middleware in the chain.

We can use the middlewares using app.use. That will apply for all request. If you want to be more specific, you can use app.verb. For instance: app.get, app.delete, app.post, app.update, …

Let’s give some examples of middlewares to drive the point home.

Say you want to log the IP of the client on each request:

app.use(function (req, res, next) {
  var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  console.log('Client IP:', ip);
  next();
});

Notice that each middleware has 3 parameters:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images

You can also specify a path that you want the middleware to activate on.

Middleware mounted on "/todos/:id" and log the request method

app.use('/todos/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

And finally you can use app.get to catch GET requests with matching routes, reply the request with a response.send and end the middleware chain. Let’s use what we learned on mongoose read to reply with the user’s data that matches the id.

Middleware mounted on "/todos/:id" and returns

app.get('/todos/:id', function (req, res, next) {
  Todo.findById(req.params.id, function(err, todo){
    if(err) res.send(err);
    res.json(todo);
  });
});

Notice that all previous middlewares called next() except this last one, because it sends a response (in JSON) to the client with the requested todo data.

Hopefully, you don’t have to develop a bunch of middlewares besides routes, since ExpressJS has a bunch of middlewares available.

4.1 Default Express 4.0 middlewares
  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
4.2 Other ExpressJS Middlewares

The following middlewares are not added by default, but it’s nice to know they exist at least:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
5. Wiring up the MEAN Stack

In the next sections, we are going to put together everything that we learn from and build an API. They can be consume by browsers, mobile apps and even other servers.

5.1 Bootstrapping ExpressJS

After a detour in the land of Node, MongoDB, Mongoose, and middlewares, we are back to our express todoApp. This time to create the routes and finalize our RESTful API.

Express has a separate package called express-generator, which can help us to get started with out API.

# install it globally using -g
npm install express-generator -g

# create todo-app API with EJS views (instead the default Jade)
express todo-api -e

#   create : todo-api
#   create : todo-api/package.json
#   create : todo-api/app.js
#   create : todo-api/public
#   create : todo-api/public/javascripts
#   create : todo-api/routes
#   create : todo-api/routes/index.js
#   create : todo-api/routes/users.js
#   create : todo-api/public/stylesheets
#   create : todo-api/public/stylesheets/style.css
#   create : todo-api/views
#   create : todo-api/views/index.ejs
#   create : todo-api/views/layout.ejs
#   create : todo-api/views/error.ejs
#   create : todo-api/public/images
#   create : todo-api/bin
#   create : todo-api/bin/www
#
#   install dependencies:
#     $ cd todo-api && npm install
#
#   run the app on Linux/Mac:
#     $ DEBUG=todo-app:* npm start
#
#   run the app on Windows:
#     $ SET DEBUG=todo-api:* & npm start

This will create a new folder called todo-api. Let’s go ahead and install the dependencies and run the app:

# install dependencies
cd todo-api && npm install

# run the app on Linux/Mac
PORT=4000 npm start

# run the app on Windows
SET PORT=4000 & npm start

Use your browser to go to http://0.0.0.0:4000, and you should see a message “Welcome to Express”

5.2 Connect ExpressJS to MongoDB

In this section we are going to access MongoDB using our newly created express app. Hopefully, you have installed MongoDB in the setup section, and you can start it by typing (if you haven’t yet):

mongod

Install the MongoDB driver for NodeJS called mongoose:

npm install mongoose --save

Notice --save. It will add it to the todo-api/package.json

Next, you need to require mongoose in the todo-api/app.js

// load mongoose package
var mongoose = require('mongoose');

// Use native Node promises
mongoose.Promise = global.Promise;

// connect to MongoDB
mongoose.connect('mongodb://localhost/todo-api')
  .then(() =>  console.log('connection succesful'))
  .catch((err) => console.error(err));

Now, When you run npm start or ./bin/www, you will notice the message connection successful. Great!

You can find the repository here and the diff code at this point: diff

5.3 Creating the Todo model with Mongoose

It’s show time! All the above was setup and preparation for this moment. Let bring the API to life.

Create a models directory and a Todo.js model:

mkdir models
touch models/Todo.js

In the models/Todo.js:

var mongoose = require('mongoose');

var TodoSchema = new mongoose.Schema({
  name: String,
  completed: Boolean,
  note: String,
  updated_at: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Todo', TodoSchema);

diff

What’s going on up there? Isn’t MongoDB suppose to be schemaless? Well, it is schemaless and very flexible indeed. However, very often we want bring sanity to our API/WebApp through validations and enforcing a schema to keep a consistent structure. Mongoose does that for us, which is nice.

You can use the following types:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images
6. API clients (Browser, Postman and curl)

I know you have not created any route yet. However, in the next sections you will. These are just three ways to retrieve, change and delete data from your future API.

6.1 Curl
# Create task
curl -XPOST http://localhost:3000/todos -d 'name=Master%20Routes&completed=false&note=soon...'

# List tasks
curl -XGET http://localhost:3000/todos

6.2 Browser and Postman

If you open your browser and type localhost:3000/todos you will see all the tasks (when you implement it). However, you cannot do post commands by default. For further testing let’s use a Chrome plugin called Postman. It allows you to use all the HTTP VERBS easily and check x-www-form-urlencoded for adding parameters.

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.## 6.3 Websites and Mobile Apps

Probably these are the main consumers of APIs. You can interact with RESTful APIs using jQuery’s $ajax and its wrappers, BackboneJS’s Collections/models, AngularJS’s $http or $resource, among many other libraries/frameworks and mobile clients.

In the end, we are going to explain how to use AngularJS to interact with this API.

7. ExpressJS Routes

To sum up we want to achieve the following:

Let’s setup the routes

mv routes/users.js routes/todos.js

In app.js add new todos route, or just replace ./routes/users for ./routes/todos

var todos = require('./routes/todos');
app.use('/todos', todos);

All set! Now, let’s go back and edit our routes/todos.js.

7.1 List: GET /todos

Remember mongoose query api? Here’s how to use it in this context:

var express = require('express');
var router = express.Router();

var mongoose = require('mongoose');
var Todo = require('../models/Todo.js');

/* GET /todos listing. */
router.get('/', function(req, res, next) {
  Todo.find(function (err, todos) {
    if (err) return next(err);
    res.json(todos);
  });
});

module.exports = router;

Harvest time! We don’t have any task in database but at least we verify it is working:

# Start database
mongod

# Start Webserver (in other terminal tab)
npm start

# Test API (in other terminal tab)
curl localhost:3000/todos
# => []%

diff

If it returns an empty array [] you are all set. If you get errors, try going back and making sure you didn’t forget anything, or you can comment at the end of the post for help.

7.2 Create: POST /todos

Back in routes/todos.js, we are going to add the ability to create using mongoose create. Can you make it work before looking at the next example?

/* POST /todos */
router.post('/', function(req, res, next) {
  Todo.create(req.body, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

diff

A few things:

  • HTTP methods, e.g. GET, PUT, DELETE, PATCH, POST, …
  • Base URI, e.g. [http://adrianmejia.com](http://adrianmejia.com "http://adrianmejia.com")
  • URL path, e.g. /blog/2014/10/01/creating-a-restful-api-tutorial-with-nodejs-and-mongodb/
  • Media type, e.g. html, JSON, XML, Microformats, Atom, Images

Everytime you change a file you have to stop and start the web server. Let’s fix that using nodemon to refresh automatically:

# install nodemon globally
npm install nodemon -g

# Run web server with nodemon
nodemon

7.3 Show: GET /todos/:id

This is a snap with [Todo.findById](https://codequs.com/p/rytO0EuH4/creating-restful-apis-with-nodejs-and-mongodb-tutorial#mongoose-read-and-query "Todo.findById") and req.params. Notice that params matches the placeholder name we set while defining the route. :id in this case.

/* GET /todos/id */
router.get('/:id', function(req, res, next) {
  Todo.findById(req.params.id, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

diff

Let’s test what we have so far!

# Start Web Server on port 4000 (default is 3000)
PORT=4000 nodemon

# Create a todo using the API
curl -XPOST http://localhost:4000/todos -d 'name=Master%20Routes&completed=false&note=soon...'
# => {"__v":0,"name":"Master Routes","completed":false,"note":"soon...","_id":"57a655997d2241695585ecf8"}%

# Get todo by ID (use the _id from the previous request, in my case "57a655997d2241695585ecf8")
curl -XGET http://localhost:4000/todos/57a655997d2241695585ecf8
{"_id":"57a655997d2241695585ecf8","name":"Master Routes","completed":false,"note":"soon...","__v":0}%

# Get all elements (notice it is an array)
curl -XGET http://localhost:4000/todos
[{"_id":"57a655997d2241695585ecf8","name":"Master Routes","completed":false,"note":"soon...","__v":0}]%

7.4 Update: PUT /todos/:id

Back in routes/todos.js, we are going to update tasks. This one you can do without looking at the example below, review findByIdAndUpdate and give it a try!

/* PUT /todos/:id */
router.put('/:id', function(req, res, next) {
  Todo.findByIdAndUpdate(req.params.id, req.body, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

diff

# Use the ID from the todo, in my case 57a655997d2241695585ecf8
curl -XPUT http://localhost:4000/todos/57a655997d2241695585ecf8 -d "note=hola"
# => {"_id":"57a655997d2241695585ecf8","name":"Master Routes","completed":true,"note":"hola","__v":0}%

7.5 Destroy: DELETE /todos/:id

Finally, the last one! Almost identical to update, use [findByIdAndRemove](https://codequs.com/p/rytO0EuH4/creating-restful-apis-with-nodejs-and-mongodb-tutorial#mongoose-delete "findByIdAndRemove").

/* DELETE /todos/:id */
router.delete('/:id', function(req, res, next) {
  Todo.findByIdAndRemove(req.params.id, req.body, function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

diff

Is it working? Cool, you are done then! Is NOT working? take a look at the full repository.

What the difference between REST API and RESTful API?

What the difference between REST API and RESTful API?

Representational state transfer (REST) is a style of software architecture. As described in a dissertation by Roy Fielding, REST is an "architectural style" that basically exploits the existing technology and protocols of the Web. RESTful is typically used to refer to web services implementing such an architecture.

The short answer is that REST stands for Representational State Transfer. It’s an architectural pattern for creating web services. A RESTful service is one that implements that pattern.

The long answer starts with “sort of” and “it depends” and continues with more complete definitions.

Defining REST

Let’s start by defining what REST is and is not. For some, REST means a server that exchanges JSON documents with a client over HTTP. Not only is that not a complete definition, but it’s also not always true. The REST specification doesn’t require HTTP or JSON. (The spec doesn’t mention JSON or XML at all.)

The Origins of REST

Roy Fielding introduced the REST architectural pattern in a dissertation he wrote in 2000. The paper defines a means for clients and servers to exchange application data. A key feature is that the client doesn’t need to know anything about the application in advance. The link is to chapter five of his paper. While the entire dissertation describes the hows and whys of REST, that chapter defines the architectural pattern.

Fielding doesn’t mandate specific requirements. Instead, he defines REST regarding constraints and architectural elements.

REST’s Architectural Constraints

Here is a summary of the constraints.

  • Client-server – REST applications have a server that manages application data and state. The server communicates with a client that handles the user interactions. A clear separation of concerns divides the two components. This means you can update and improve them in independent tracks.
  • Stateless – servers don’t maintain any client state. Clients manage their application state. Their requests to servers contain all the information required to process them.
  • Cacheable – servers must mark their responses as cacheable or not. So, infrastructures and clients can cache them when possible to improve performance. They can dispose of non-cacheable Information, so no client uses stale data.
  • Uniform interface – this constraint is REST’s most well known feature or rule, depending on who you ask. Fielding says “The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components.” REST services provide data as resources, with a consistent namespace. We’ll cover this in detail below.
  • Layered system – components in the system cannot “see” beyond their layer. So, you can easily add load-balancers and proxies to improve security or performance.

A RESTful service is more than a web server that exchanges JSON, or any other, documents. These constraints work together to create a very specific type of application.

Applying the Constraints

First, the client-server, layered systems and stateless constraints combine to form an application with solid boundaries and clear separations between concerns. Data moves from the server to the client upon request. The client displays or manipulates it. If the state changes, the client sends it back to the server for storage. Fielding specifically contrasts REST with architectures that use distributed objects to hide data from other components. In REST, the client and server share knowledge about data and state. The architecture doesn’t conceal data, it only hides implementations.

The cacheable and uniform state constraints go one step further. Application data is available to clients in a clear and consistent interface and cached when possible.

So, that’s the technical definition of REST. What does it look like in the real world?

RPC Over HTTP vs. RESTful

Often when someone says that a service “isn’t REST,” they’re looking at the URIs or how the service uses HTTP verbs. They’re referring to REST’s presentation of data as a uniform set of resources.

This distinction is sometimes framed as a difference between remote procedures calls (RPC) and REST. Imagine a web service for listing, adding, and removing, items from an e-commerce inventory.

In one version, there’s a single URL that we query with HTTP GETs or POSTs.  You interact with the service by POSTing a document, setting the contents to reflect what you want to do.

Add new items with a POST with a NewItem:

POST /inventory HTTP/1.1
 
{
    "NewItem": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

Query for items with a POST and an ItemRequest:

POST /inventory HTTP/1.1
 
{
    "ItemRequest": {
          "id": "1001"
      }
}

Some implementations accept a request for a new item with a get, too.

POST /inventory?id=1001 HTTP/1.1

We also change or delete items with a POST and an ItemDelete or ItemUpdate.

POST /inventory HTTP/1.1
 
{
    "ItemDelete": {
          "id": "1001"
      }
}

This isn’t REST. We’re not exchanging the state of resources. We’re calling a function with arguments that happen to be in a JSON document or URL arguments.

A RESTful service has a URI for each item in the inventory.

So, adding a new item would look like the example above.

POST /item HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

But the similarities end there. Retrieving an item is always a GET:

GET /item/1001 HTTP/1.1   

Deleting is a DELETE:

DELETE /item/1001 HTTP/1.1  

Modifying an item is a PUT:

POST /inventory HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "7.99",
          "id": "1001"
      }
}    

The difference is important. In REST, operations that use distinct HTTP actions. These verbs correspond directly to the activity on the data. GET, POST, PUT, DELETE and PATCH all have specific contracts. Most well-designed REST APIs also return specific HTTP codes, depending on the result of the request.

The critical point is that the URIs operate on the data, not on remote methods.

But there’s another reason why the resource model is essential.

REST vs RESTful and the Richardson Maturity Model

When you model your URIs after resources and use HTTP verbs you make your API predictable. Once developers know how you defined your resources, they can almost predict what the API looks like. Here again, the emphasis is on understanding the data, not the operations.

But even if you can’t make the API entirely predictable, you can document any REST service with hypertext. So, each item returned in the inventory app would contain links for deleting, modifying, or setting the inventory level of the resource. Fielding says that before a service is RESTful, it must provide hypertext media as part of the API.

Many sites don’t meet this requirement but are still called REST. Fact is, many sites break the rules in one way or another. So many that Leonard Richardson created a model breaks down REST into levels of compliance

We’ve already covered the source levels:

  • 0 – exporting an API over HTTP with methods called with arguments
  • 1 – Exporting resources instead of methods
  • 2 – Proper use of HTTP verbs
  • 3 – Exporting hypertext with objects that make all or part of the API discoverable.

Richardson’s model is his own, and it doesn’t map directly into Fielding’s spec. Since Fielding requires level three, he would say that most apps aren’t REST anyway.

The point is many services that we colloquially refer to as REST, technically aren’t.

REST vs RESTful: Does It Matter?

So, does the REST vs. RESTful comparison matter? Probably not. How well your architecture complies with an arbitrary standard isn’t as important with how well it suits your needs and can grow with your business.

The REST architectural pattern has many advantages. Fielding designed it for the web and, 18 years later, most of the constraints he had in mind are still with us. In 2000 we didn’t have Android or the iPhone. IE5 had 50% of the browser market share. It’s biggest rival was Firefox. But Fielding recognized what online applications needed and how web clients would evolve from HTML display engines into complete applications. The tools we use today have grown to suit REST, not the other way around.

Thank you for reading. Hope this tutorial will help you!