95
@jakobmattsson

Writing RESTful web services using Node.js

  • Upload
    fdconf

  • View
    23.446

  • Download
    5

Embed Size (px)

DESCRIPTION

by Jakob Mattsson on Frontend DEV Conf'13 http://bit.ly/Jakob_Mattsson

Citation preview

Page 1: Writing RESTful web services using Node.js

@jakobmattsson

Page 2: Writing RESTful web services using Node.js
Page 3: Writing RESTful web services using Node.js

Started out doing consulting

Page 4: Writing RESTful web services using Node.js

3 startups:RecruitingAdvertisingFeedback

Page 5: Writing RESTful web services using Node.js

2 000 000 000 writes/day!

Page 6: Writing RESTful web services using Node.js

Back to square one

Page 7: Writing RESTful web services using Node.js

Writing RESTfulweb servicesusing Node.js

Page 8: Writing RESTful web services using Node.js

Comparison

Rocket science

Product demo

Silver bullet

Page 9: Writing RESTful web services using Node.js

Comparison

Rocket science

Product demo

Silver bulletNOT

Page 10: Writing RESTful web services using Node.js

What is it then?

Page 11: Writing RESTful web services using Node.js

Imagination

Quantity

Bottom up

Principles

Page 12: Writing RESTful web services using Node.js

Also... CoffeeScript

Page 13: Writing RESTful web services using Node.js

Node.js

Page 14: Writing RESTful web services using Node.js
Page 15: Writing RESTful web services using Node.js

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast,

scalable network applications.

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient,

perfect for data-intensive real-time applications that run across distributed devices.

Page 16: Writing RESTful web services using Node.js

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast,

scalable network applications.

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient,

perfect for data-intensive real-time applications that run across distributed devices.

Page 17: Writing RESTful web services using Node.js

fs = require('fs')

fs.readFile 'meaning_of_life.txt', 'utf-8', (err, data) -> console.log(data)

console.log('end')

Page 18: Writing RESTful web services using Node.js

end42

Page 19: Writing RESTful web services using Node.js

Several protocols,including TCP and HTTP,

are built in to node.

Page 20: Writing RESTful web services using Node.js

http = require('http')

onRequest = (req, res) -> res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('Hello World\n')

http.createServer(onRequest).listen(1337)

Page 21: Writing RESTful web services using Node.js

npm

Page 22: Writing RESTful web services using Node.js

npm is a package manager for node.

You can use it to install and publish your node programs.

”It manages dependencies and does other cool stuff.”

Page 23: Writing RESTful web services using Node.js

npm install underscore

Page 24: Writing RESTful web services using Node.js

_ = require('underscore')numbers = _.range(1, 10)console.log(_.last(numbers))

Page 25: Writing RESTful web services using Node.js

Connect

Page 26: Writing RESTful web services using Node.js

Connect is a midleware framework for node.

It’s shipping with over 18 bundled middleware.

It has a rich selection of 3rd-party middleware.

Page 27: Writing RESTful web services using Node.js

npm install connect

Page 28: Writing RESTful web services using Node.js

connect = require('connect')app = connect()app.listen(3000)

// last line equivalent to // http.createServer(app).listen(3000);

Page 29: Writing RESTful web services using Node.js

connect = require('connect')app = connect()

app.use connect.basicAuth (user, pass) -> return user == 'jakob' && pass == 'fdc13'

app.use (req, res) -> res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('Hello World\n')

app.listen(3000)

Page 30: Writing RESTful web services using Node.js

logger csrf

compress basicAuth

bodyParser json

urlencoded multipart

cookieParser session

cookieSession methodOverride

responseTime staticCache

static directory

vhost favicon

limit query

errorHandler

Request logger with custom format supportCross-site request forgery protectionGzip compression middlewareBasic http authenticationExtensible request body parserApplication/json parserApplication/x-www-form-urlencoded parserMultipart/form-data parserCookie parserSession management support with bundled MemoryStoreCookie-based session supportFaux HTTP method supportCalculates response-time and exposes via X-Response-TimeMemory cache layer for the static() middlewareStreaming static file server supporting Range and moreDirectory listing middlewareVirtual host sub-domain mapping middlewareEfficient favicon server (with default icon)Limit the bytesize of request bodiesAutomatic querystring parser, populating req.queryFlexible error handler

Page 31: Writing RESTful web services using Node.js

Express

Page 32: Writing RESTful web services using Node.js

High performancehigh class web development

for Node.js

Page 33: Writing RESTful web services using Node.js

npm install express

Page 34: Writing RESTful web services using Node.js

express = require('express')app = express.createServer()

app.get '/', (req, res) -> res.send('Hello World')

app.get '/users/:id', (req, res) -> res.send('user ' + req.params.id)

app.listen(3000)

Page 35: Writing RESTful web services using Node.js

express = require('express')app = express.createServer()

before1 = (req, res, next) -> req.foo = 'bar' next()

before2 = (req, res, next) -> res.header('X-Time', new Date().getTime()) next()

app.get '/', before1, (req, res) -> res.send('Hello World')

app.get '/users/:id', [before1, before2], (req, res) -> console.log(req.foo) res.send('user ' + req.params.id)

app.listen(3000)

Page 36: Writing RESTful web services using Node.js

Data storage

Page 37: Writing RESTful web services using Node.js

But which one?

Page 38: Writing RESTful web services using Node.js

Schemaless is a lie

Page 39: Writing RESTful web services using Node.js
Page 40: Writing RESTful web services using Node.js

Mongoose

Page 41: Writing RESTful web services using Node.js

Mongoose is a MongoDB object modeling tool

designed to work in an asynchronous environment.

Page 42: Writing RESTful web services using Node.js

npm install mongoose

Page 43: Writing RESTful web services using Node.js

mongoose = require 'mongoose'

mongoose.connect 'mongodb://localhost/tamblr'

model = (name, schema) -> mongoose.model name, new mongoose.Schema schema, strict: true

users = model 'users' name: type: String default: '' bio: type: String default: 'IE6-lover' age: type: Number default: null

Page 44: Writing RESTful web services using Node.js

blogs = model 'blogs' name: type: String default: '' description: type: String default: '' users: type: ObjectId ref: 'users'

Page 45: Writing RESTful web services using Node.js

posts = model 'posts' title: type: String default: '' body: type: String default: '' published: type: Date blogs: type: ObjectId ref: 'blogs'

Page 46: Writing RESTful web services using Node.js

list = (model, callback) -> model.find {}, callback

get = (model, id, callback) -> model.findById id, callback

del = (model, id, callback) -> model.remove { _id: id }, callback

put = (model, id, data, callback) -> model.update { _id: id }, data, { multi: false }, callback

post = (model, data, callback) -> new model(data).save callback

Page 47: Writing RESTful web services using Node.js

app.get '/users/:id', (req, res) -> get users, req.params.id, (err, data) -> res.json data

Page 48: Writing RESTful web services using Node.js

copy-paste!

Page 49: Writing RESTful web services using Node.js

POST /usersGET /usersGET /users/42DELETE /users/42PUT /users/42

POST /blogsGET /blogsGET /blogs/42DELETE /blogs/42PUT /blogs/42

POST /postsGET /postsGET /posts/42DELETE /posts/42PUT /posts/42

Page 50: Writing RESTful web services using Node.js

or should we?

Page 51: Writing RESTful web services using Node.js

models = [users, blogs, posts]

Object.keys(models).forEach (modelName) ->

app.get "/#{modelName}", (req, res) -> list models[modelName], (err, data) -> res.json data

app.get "/#{modelName}/:id", (req, res) -> get models[modelName], req.params.id, (err, data) -> res.json data

app.post "/#{modelName}", (req, res) -> post models[modelName], req.body, (err, data) -> res.json data

app.del "/#{modelName}/:id", (req, res) -> del models[modelName], req.parmas.id, (err, count) -> res.json { count: count }

app.put "/#{modelName}/:id", (req, res) -> put models[modelName], req.params.id, req.body, (err, count) -> res.json { count: count }

Page 52: Writing RESTful web services using Node.js

POST /usersGET /usersGET /users/42DELETE /users/42PUT /users/42

POST /blogsGET /blogsGET /blogs/42DELETE /blogs/42PUT /blogs/42

POST /postsGET /postsGET /posts/42DELETE /posts/42PUT /posts/42

Page 53: Writing RESTful web services using Node.js

But what about the relations/associations?

Page 54: Writing RESTful web services using Node.js

POST /users/42/blogsGET /users/42/blogs

POST /blogs/42/postsGET /blogs/42/posts

Page 55: Writing RESTful web services using Node.js

paths = models[modelName].schema.pathsowners = Object.keys(paths).filter (p) -> paths[p].options.type == ObjectId && typeof paths[p].options.ref == 'string'.map (x) -> paths[x].options.ref

owners.forEach (owner) ->

app.get "/#{owner}/:id/#{name}", (req, res) -> listSub models[name], owner, req.params.id, (err, data) -> res.json data

app.post "/#{owner}/:id/#{name}", (req, res) -> postSub models[name], req.body, owner, req.params.id, (err, data) -> res.json data

Page 56: Writing RESTful web services using Node.js

POST /users/42/blogsGET /users/42/blogs

POST /blogs/42/postsGET /blogs/42/posts

Page 57: Writing RESTful web services using Node.js

Keep on generating!

Page 58: Writing RESTful web services using Node.js

Authentication

Page 59: Writing RESTful web services using Node.js

npm install passportnpm install passport-local

Page 60: Writing RESTful web services using Node.js

passport = require('passport')passportLocal = require('passport-local')

passport.use new passportLocal.Strategy (user, pass, done) -> findUserPlz { username: user, password: pass }, (err, user) -> done(err, user)

app.use(passport.initialize())app.use(passport.authenticate('local'))

Page 61: Writing RESTful web services using Node.js

npm install passport-twitter

Page 62: Writing RESTful web services using Node.js

passport = require('passport')twitter = require('passport-twitter')

keys = { consumerKey: TWITTER_CONSUMER_KEY consumerSecret: TWITTER_CONSUMER_SECRET callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"}

passport.use new twitter.Strategy keys, (t, ts, profile, done) -> findOrCreateUserPlz { twitterId: profile.id }, (err, user) -> done(err, user)

app.use(passport.initialize())app.use(passport.authenticate('twitter'))

Page 63: Writing RESTful web services using Node.js

Part 2Convention

Page 64: Writing RESTful web services using Node.js

ALL CHARACTERS ANDEVENTS IN THIS SHOW--

EVENT THOSE BASED ON REALPEOPLE--ARE ENTIRELY FICTIONAL.

ALL CELEBERTY VOICES AREIMPERSONATED.....POORLY. THE

FOLLOWING PROGRAM CONTAINSCOARSE LANGUAGE AND DUE TOITS CONTENT IT SHOULD NOT BE

VIEWED BE ANYONE

Page 65: Writing RESTful web services using Node.js

Verbs vs Nouns

Page 66: Writing RESTful web services using Node.js

/users/users/42

/blogs/blogs/73

/posts/posts/314

Page 67: Writing RESTful web services using Node.js

GET /usersGET /users/42

POST /users

PUT /users/42

DELETE /usersDELETE /users/42

Page 68: Writing RESTful web services using Node.js

Associations

Page 69: Writing RESTful web services using Node.js

/users/blogs/posts

Page 70: Writing RESTful web services using Node.js

/users/blogs/posts

/users/42/blogs/blogs/314/posts

Page 71: Writing RESTful web services using Node.js

/users/blogs/posts

/users/42/blogs/blogs/314/posts

/users/42/blogs/314/posts

Page 72: Writing RESTful web services using Node.js

/users/blogs/posts

/users/42/blogs/blogs/314/posts

/users/42/blogs/314/posts

Page 73: Writing RESTful web services using Node.js

/users/blogs/posts

/users/42/blogs/blogs/314/posts

/users/42/blogs/314/posts

Keep URLs short. Don’t overqualify.

Page 74: Writing RESTful web services using Node.js

GET /blogs/42/posts?tag=javascript

Page 75: Writing RESTful web services using Node.js

Versions

Page 76: Writing RESTful web services using Node.js

GET /v1/users

Page 77: Writing RESTful web services using Node.js

Partial responses

Page 78: Writing RESTful web services using Node.js

GET /users?fields=email,age

GET /users?limit=10&offset=0

Page 79: Writing RESTful web services using Node.js

Verbs

Page 80: Writing RESTful web services using Node.js

/convert?from=EUR&to=BYR&amount=100

Page 81: Writing RESTful web services using Node.js

Content-types

Page 82: Writing RESTful web services using Node.js

GET /v1/users/42.xml

Page 83: Writing RESTful web services using Node.js

Attributes

Page 84: Writing RESTful web services using Node.js

{ "userId": 1, "firstName": "Jakob", "lastName": "Mattsson"}

Page 85: Writing RESTful web services using Node.js

Search

Page 86: Writing RESTful web services using Node.js

GET /search?q=javascriptGET /blog/42/posts?q=javascript

Page 87: Writing RESTful web services using Node.js

Authentication

Page 88: Writing RESTful web services using Node.js

Part 3Conclusion

Page 89: Writing RESTful web services using Node.js
Page 90: Writing RESTful web services using Node.js

It goes for ideas too!

Reuse convention.

Page 91: Writing RESTful web services using Node.js

Reuse code.

Resuse ideas.

Build new things.

Page 92: Writing RESTful web services using Node.js
Page 93: Writing RESTful web services using Node.js
Page 94: Writing RESTful web services using Node.js

”MOST IMPORTANT STEPFOR BUILD PRODUCTIS BUILD PRODUCT”

- @fakegrimlock

Page 95: Writing RESTful web services using Node.js

@jakobmattsson

Thank you!