SlideShare a Scribd company logo
Building a Node.js Client
for Your REST+JSON API
Les Hazlewood @lhazlewood
CTO, Stormpath stormpath.com
.com
• User Management and Authentication
API
• Security for your applications
• User security workflows
• Security best practices
• Developer tools, SDKs, libraries
Overview
• Resources
• Public / Private API
• Proxy Design
• Active Record
• Fluent API
• Configuration
• Caching
• Authentication
• Pluggability
• Lessons Learned
HATEOAS
• Hypermedia
• As
• The
• Engine
• Of
• Application
• State
Learn more at Stormpath.com
Resources
Learn more at Stormpath.com
Resources
• Nouns, not verbs
• Coarse-grained, not fine-grained
• Support many use cases
• Globally unique HREF
Learn more at Stormpath.com
Collection Resource
• Example:
/applications
• First class resource w/ own properties:
• offset
• limit
• items
• first, next, previous, last
• etc
• items contains instance resources
Learn more at Stormpath.com
Instance Resource
• Example:
/applications/8sZxUoExA30mP74
• Child of a collection
• RUD (no Create - done via parent collection)
Learn more at Stormpath.com
Translating to Code
Learn more at Stormpath.com
Resource
var util = require('util');
function Resource(...) { ... }
util.inherits(Resource, Object);
someResource.href
Learn more at Stormpath.com
Instance Resource
function InstanceResource(...) {...}
util.inherits(InstanceResource, Resource);
anInstanceResource.save(function (err, saved) {
...
});
anInstanceResource.delete(function (err) {
...
});
Learn more at Stormpath.com
Collection Resource
function CollectionResource(...) {...}
util.inherits(CollectionResource, Resource);
aCollResource.each(function (item, callback) {
...
}, function onCompletion(err) {
...
});
aCollResource.eachSeries
aCollResource.map
aCollResource.filter
... other async.js methods ...
Learn more at Stormpath.com
Example: ApplicationList
applications.each(function(app, callback){
console.log(app);
callback();
}, function finished(err) {
if (err) console.log(„Error: „ + err);
});
Learn more at Stormpath.com
Design!
Learn more at Stormpath.com
Encapsulation
• Public API
• Internal/Private Implementations
• Extensions
• Allows for change w/ minimal impact
http://semver.org
Learn more at Stormpath.com
Encapsulation in practice
• Use an underscore prefix: _
• Super clear code comments:
mark @public or @private
• Public API docs: don’t display private
classes/methods/functions
Learn more at Stormpath.com
Public API
Learn more at Stormpath.com
Public API
• All non-@private functions/vars
• Builder methods (method chaining)
• Object literals (config) is public too!
Learn more at Stormpath.com
Public prototypical OO Classes
• Client
• ApiKey
• Application
• Directory
• Account
• Group
• etc
Learn more at Stormpath.com
Classes with static helper methods
Client client = Clients.builder()
...
.build();
• Create multiple helper classes
separation of concerns
Learn more at Stormpath.com
Builder methods (method chaining)
client.getApplications()
.where(name).startsWith(„*foo‟)
.orderBy(name).asc()
.limit(10)
.execute(function (err, apps){
...
});
clients.getApplications()  ApplicationRequestBuilder
Single Responsibility Principle!
Learn more at Stormpath.com
Private API
• Implementations + SPI interfaces
• Builder implementations
• Implementation Plugins
Learn more at Stormpath.com
Resource Implementations
• Create a base Resource class:
• Property manipulation methods
• Dirty checking
• Reference to DataStore
• Lazy Loading
• Create base InstanceResource and CollectionResource
implementations
• Extend from InstanceResource or CollectionResource
Learn more at Stormpath.com
Resource
var utils = require(‟utils');
function Resource(data, dataStore) {
var DataStore = require('../ds/DataStore');
if (!dataStore && data instanceof DataStore){
dataStore = data;
data = null;
}
data = data || {};
for (var key in data) {
if (data.hasOwnProperty(key)) {
this[key] = data[key];
}
}
var ds = null; //private var, not enumerable
Object.defineProperty(this, 'dataStore', {
get: function getDataStore() {
return ds;
},
set: function setDataStore(dataStore) {
ds = dataStore;
}
});
if (dataStore) {
this.dataStore = dataStore;
}
}
utils.inherits(Resource, Object);
module.exports = Resource;
Learn more at Stormpath.com
InstanceResource
var utils = require(„utils');
var Resource = require('./Resource');
function InstanceResource() {
InstanceResource.super_.apply(this, arguments);
}
utils.inherits(InstanceResource, Resource);
InstanceResource.prototype.save = function
saveResource(callback) {
this.dataStore.saveResource(this, callback);
};
InstanceResource.prototype.delete = function
deleteResource(callback) {
this.dataStore.deleteResource(this, callback);
};
Learn more at Stormpath.com
Application
var utils = require(„utils');
var InstanceResource = require('./InstanceResource');
function Application() {
Application.super_.apply(this, arguments);
}
utils.inherits(Application, InstanceResource);
Application.prototype.getAccounts = function
getApplicationAccounts(/* [options,] callback */) {
var self = this;
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
var options = (args.length > 0) ? args.shift() : null;
return self.dataStore.getResource(self.accounts.href, options,
require('./Account'), callback);
};
Learn more at Stormpath.com
Usage Paradigm
Learn more at Stormpath.com
Account JSON Resource
{
“href”: “https://api.stormpath.com/v1/accounts/x7y8z9”,
“givenName”: “Tony”,
“surname”: “Stark”,
…,
“directory”: {
“href”:
“https://api.stormpath.com/v1/directories/g4h5i6”
}
}
Learn more at Stormpath.com
Proxy Pattern
String href = “https://api.stormpath.com/v1/....”;
client.getAccount(href, function(err, acct) {
if (err) throw err;
account.getDirectory(function(err, dir) {
if (err) throw err;
console.log(dir);
});
});
Learn more at Stormpath.com
Proxy Pattern
Learn more at Stormpath.com
Component Architecture
Learn more at Stormpath.com
Component Architecture
account .save()
Learn more at Stormpath.com
Component Architecture
account .save()
DataStore
Learn more at Stormpath.com
Component Architecture
account .save()
Cache
Manager
DataStore
Learn more at Stormpath.com
Component Architecture
account .save()
Cache
Manager
DataStore
Cache
Cache
Cache
Learn more at Stormpath.com
Component Architecture
account .save()
RequestExecutorCache
Manager
DataStore
Cache
Cache
Cache
Learn more at Stormpath.com
Component Architecture
account .save()
RequestExecutor
Authentication
Strategy
Cache
Manager
DataStore
Request
Authenticator
Cache
Cache
Cache
Learn more at Stormpath.com
Component Architecture
account
API Server
.save()
RequestExecutor
Authentication
Strategy
Cache
Manager
DataStore
Request
Authenticator
Cache
Cache
Cache
Learn more at Stormpath.com
Component Architecture
account
API Server
.save()
RequestExecutor ResourceFactory
JSON  Resource
Authentication
Strategy
Cache
Manager
DataStore
Request
Authenticator
Cache
Cache
Cache
Learn more at Stormpath.com
Caching
Learn more at Stormpath.com
Caching
var cache = cacheManager.getCache(regionName);
cache.ttl //time to live
cache.tti //time to idle
cache.get(href, function(err, obj) {
...
});
Learn more at Stormpath.com
Caching
client.getAccount(href, function(err, acct) {...});
// in the DataStore:
var cache = cacheManager.getCache(„accounts‟);
cache.get(href, function(err, entry) {
if (err) return callback(err);
if (entry) {
... omitted for brevity ...
return callback(entry.value);
}
//otherwise, cache miss – execute a request:
requestExecutor.get(href, function(err, body) {
//1. cache body
//2. convert to Resource instance
//3. invoke callback w/ instance
}
}
Learn more at Stormpath.com
Queries
Learn more at Stormpath.com
Queries
account.getGroups(function(err,groups){...});
//results in a request to:
//https://api.stormpath.com/v1/accounts/a1b2c3/groups
• What about query parameters?
Learn more at Stormpath.com
Queries
account.getGroups(
{
name: „foo*‟,
description: „*test*‟,
orderBy: „name desc‟,
limit: 100
},
function onResult(err, groups) {
...
}
);
//results in a request to:
https://api.stormpath.com/v1/accounts/a1b2c3/groups?
name=foo*&description=*test*&orderBy=name%20desc&limit=100
Learn more at Stormpath.com
Queries
Use a Fluent API!
Learn more at Stormpath.com
Queries
account.getGroups().where()
.name().startsWith(“foo”)
.description().contains(“test”)
.orderBy(“name”).desc()
.limitTo(100)
);
//results in a request to:
https://api.stormpath.com/v1/accounts/a1b2c3/groups?
name=foo*&description=*test*&orderBy=name%20desc&limit=100
Learn more at Stormpath.com
Authentication
Learn more at Stormpath.com
Authentication
• Favor a digest algorithm over HTTP Basic
• Prevents Man-in-the-Middle attacks (SSL won’t guarantee
this!)
• Also support Basic for environments that require it (Dammit
Google!)
• ONLY use Basic over SSL
• Represent this as an AuthenticationScheme to your Client /
RequestExecutor
Learn more at Stormpath.com
Authentication
• AuthenticationScheme.SAUTHC1
• AuthenticationScheme.BASIC
• AuthenticationScheme.OAUTH10a
• ... etc ...
Client client = new stormpath.Client({
//defaults to sauthc1
authcScheme: „basic‟
});
Client/RequestExecutor uses a Sauthc1RequestAuthenticator or
BasicRequestAuthenticator or OAuth10aRequestAuthenticator, etc.
Learn more at Stormpath.com
Plugins
Learn more at Stormpath.com
Plugins
• Plugins or Extensions module
• One sub-module per plugin
• Keep dependencies to a minimum
plugins/
|- request/
|- foo/
Learn more at Stormpath.com
Lessons Learned
Learn more at Stormpath.com
Lessons Learned
• Recursive caching if you support resource
expansion
• Dirty checking logic is not too hard, but it does
add complexity. Start off without it.
Learn more at Stormpath.com
Lessons Learned: Promises
var promise = account.getGroups();
promise.then(function() {
//called on success
}, function() {
//called on error
}, function() {
//called during progress
});
Learn more at Stormpath.com
Lessons Learned: async.js
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
},
function(arg1, callback){
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
Learn more at Stormpath.com
Code
$ git clone
https://github.com/stormpath/stormpath-sdk-
node.git
$ cd stormpath-sdk-node
$ npm install
$ grunt
Learn more at Stormpath.com
Thank You!
• les@stormpath.com
• Twitter: @lhazlewood
• http://www.stormpath.com
Learn more at Stormpath.com

More Related Content

PPTX
Elegant Rest Design Webinar
PPTX
REST API Design for JAX-RS And Jersey
PPTX
Build A Killer Client For Your REST+JSON API
PPTX
Secure Your REST API (The Right Way)
PDF
Secure Web Services
PDF
Securing REST APIs
PPTX
Rest API Security
PDF
Building an API Security Ecosystem
Elegant Rest Design Webinar
REST API Design for JAX-RS And Jersey
Build A Killer Client For Your REST+JSON API
Secure Your REST API (The Right Way)
Secure Web Services
Securing REST APIs
Rest API Security
Building an API Security Ecosystem

What's hot (20)

PDF
Rest Security with JAX-RS
PDF
Secure java script-for-developers
PDF
Super simple application security with Apache Shiro
PPTX
Making Sense of API Access Control
PDF
Using OAuth with PHP
ODP
Mohanraj - Securing Your Web Api With OAuth
PPTX
Enterprise Access Control Patterns for REST and Web APIs Gluecon 2011, Franco...
PPTX
Instant Security & Scalable User Management with Spring Boot
PDF
Securty Testing For RESTful Applications
PPTX
Securing Single Page Applications with Token Based Authentication
KEY
Advanced CSRF and Stateless Anti-CSRF
PPTX
Top Ten Java Defense for Web Applications v2
PPTX
Secure RESTful API Automation With JavaScript
PDF
Securing Web Applications with Token Authentication
PPTX
Beautiful REST+JSON APIs with Ion
PPT
Top Ten Web Application Defenses v12
PPTX
Secureyourrestapi 140530183606-phpapp02
PPT
External Data Access with jQuery
PPTX
Cross Site Scripting (XSS) Defense with Java
ODP
Attacking REST API
Rest Security with JAX-RS
Secure java script-for-developers
Super simple application security with Apache Shiro
Making Sense of API Access Control
Using OAuth with PHP
Mohanraj - Securing Your Web Api With OAuth
Enterprise Access Control Patterns for REST and Web APIs Gluecon 2011, Franco...
Instant Security & Scalable User Management with Spring Boot
Securty Testing For RESTful Applications
Securing Single Page Applications with Token Based Authentication
Advanced CSRF and Stateless Anti-CSRF
Top Ten Java Defense for Web Applications v2
Secure RESTful API Automation With JavaScript
Securing Web Applications with Token Authentication
Beautiful REST+JSON APIs with Ion
Top Ten Web Application Defenses v12
Secureyourrestapi 140530183606-phpapp02
External Data Access with jQuery
Cross Site Scripting (XSS) Defense with Java
Attacking REST API
Ad

Viewers also liked (20)

PPTX
So long scrum, hello kanban
PPTX
Secure API Services in Node with Basic Auth and OAuth2
PPTX
Storing User Files with Express, Stormpath, and Amazon S3
PDF
Building Beautiful REST APIs in ASP.NET Core
PPTX
JWTs for CSRF and Microservices
PDF
Mobile Authentication for iOS Applications - Stormpath 101
PPTX
Token Authentication in ASP.NET Core
PPTX
Building Secure User Interfaces With JWTs (JSON Web Tokens)
PPTX
Custom Data Search with Stormpath
PPTX
Spring Boot Authentication...and More!
PPTX
Stormpath 101: Spring Boot + Spring Security
PDF
JWTs in Java for CSRF and Microservices
PDF
Getting Started With Angular
PPTX
Multi-Tenancy with Spring Boot
PDF
The Ultimate Guide to Mobile API Security
PDF
Build a REST API for your Mobile Apps using Node.js
PPTX
Token Authentication for Java Applications
PDF
Building Beautiful REST APIs with ASP.NET Core
PPTX
Browser Security 101
PPTX
REST API Security: OAuth 2.0, JWTs, and More!
So long scrum, hello kanban
Secure API Services in Node with Basic Auth and OAuth2
Storing User Files with Express, Stormpath, and Amazon S3
Building Beautiful REST APIs in ASP.NET Core
JWTs for CSRF and Microservices
Mobile Authentication for iOS Applications - Stormpath 101
Token Authentication in ASP.NET Core
Building Secure User Interfaces With JWTs (JSON Web Tokens)
Custom Data Search with Stormpath
Spring Boot Authentication...and More!
Stormpath 101: Spring Boot + Spring Security
JWTs in Java for CSRF and Microservices
Getting Started With Angular
Multi-Tenancy with Spring Boot
The Ultimate Guide to Mobile API Security
Build a REST API for your Mobile Apps using Node.js
Token Authentication for Java Applications
Building Beautiful REST APIs with ASP.NET Core
Browser Security 101
REST API Security: OAuth 2.0, JWTs, and More!
Ad

Similar to Build a Node.js Client for Your REST+JSON API (20)

PDF
From System Engineer to Gopher
PDF
Tutorial, Part 2: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
PDF
2020-02-20 - HashiTalks 2020 - HashiCorp Vault configuration as code via Hash...
PPTX
Introduction to Monsoon PHP framework
PPTX
OpenCMIS Part 1
PDF
HTTP Caching and PHP
PPT
aksdfhaskdjfhasdjkh
PPT
askldjfhaskdfj aslkdjfhaskdfhasjk askldf ashkdf
PPT
aergserga
PPT
salkdjfhdjkghdfkjh
PPT
awergaezrg
PPT
sergaerwga
PPT
sakdjfhaksjfhaskjh
PPTX
Beautiful REST and JSON APIs - Les Hazlewood
PDF
An Introduction to Tornado
PPTX
StackMate - CloudFormation for CloudStack
PDF
Web Standards Support in WebKit
PDF
HashiConf Digital 2020: HashiCorp Vault configuration as code via HashiCorp T...
PDF
Immutable Deployments with AWS CloudFormation and AWS Lambda
PDF
AWS Java SDK @ scale
From System Engineer to Gopher
Tutorial, Part 2: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
2020-02-20 - HashiTalks 2020 - HashiCorp Vault configuration as code via Hash...
Introduction to Monsoon PHP framework
OpenCMIS Part 1
HTTP Caching and PHP
aksdfhaskdjfhasdjkh
askldjfhaskdfj aslkdjfhaskdfhasjk askldf ashkdf
aergserga
salkdjfhdjkghdfkjh
awergaezrg
sergaerwga
sakdjfhaksjfhaskjh
Beautiful REST and JSON APIs - Les Hazlewood
An Introduction to Tornado
StackMate - CloudFormation for CloudStack
Web Standards Support in WebKit
HashiConf Digital 2020: HashiCorp Vault configuration as code via HashiCorp T...
Immutable Deployments with AWS CloudFormation and AWS Lambda
AWS Java SDK @ scale

Recently uploaded (20)

PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
AI in Product Development-omnex systems
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
System and Network Administraation Chapter 3
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
ai tools demonstartion for schools and inter college
PDF
top salesforce developer skills in 2025.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
PTS Company Brochure 2025 (1).pdf.......
How to Choose the Right IT Partner for Your Business in Malaysia
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Wondershare Filmora 15 Crack With Activation Key [2025
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
AI in Product Development-omnex systems
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Design an Analysis of Algorithms II-SECS-1021-03
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
System and Network Administraation Chapter 3
Operating system designcfffgfgggggggvggggggggg
ai tools demonstartion for schools and inter college
top salesforce developer skills in 2025.pdf
How Creative Agencies Leverage Project Management Software.pdf
Odoo POS Development Services by CandidRoot Solutions
PTS Company Brochure 2025 (1).pdf.......

Build a Node.js Client for Your REST+JSON API