Slide 1

Slide 1 text

1 A comparison of Node.js server frameworks joseph-norman @joemismatch http://joseph-norman.github.io/

Slide 2

Slide 2 text

2 JavaScript developer @ Bede Gaming Who am I? Main project - dev & support for large scale API facade (in Hapi.js) Rewriting a slots game engine server (currently in Hapi.js) (Rarely) client side JS adding new features & bug fixes to slots games (Backbone.Marionette, Phaser, Pixi.js) Side projects An (in-progress) pluralsight author for upcoming course, "RESTful API design and implementation using Hapi.js" Writing 'Knots' - An interactive localised JavaScript / Node.js compiler / debugger / static analysis tool (think IDE debugger but in Sublime Text!)

Slide 3

Slide 3 text

3 Servers What is node.js? Why node.js? require('http'); Express & Koa Hapi.js Sails (MVC) Conclusion Questions? What's covered today

Slide 4

Slide 4 text

4 Moving from Frontend -> Backend Coding

Slide 5

Slide 5 text

5 Servers - the relationship between client & server All content you access from a browser is 'served' Actions like grabbing data, logging in, updating data, etc. Are all part of this process. More often this process needs to be dynamic i.e in single page applications. A good analogy is the idea of a restaurant

Slide 6

Slide 6 text

6 Introduction to Node.js Localised JavaScript runtime, utilising (currently) the Google V8 Engine. Runtime = your code executor Includes a REPL (Read Eval Print Loop) Ships with a great library, and its own package manager (npm) Has had an explosion in popularity

Slide 7

Slide 7 text

7 Why node.js? The event based server execution (a.k.a the 'event loop') No waiting for I/O blockers (file reading, accessing external web services, external device reads, anything considered blocking). Uses Google's lightning fast V8 Engine (also used in Chrome), will also have the option for Microsoft's IoT Chakra engine in the near future. Tremendous global popularity. Support everywhere! Transferable knowledge from frontend JavaScript

Slide 8

Slide 8 text

8 "To use the HTTP server and client one must require('http')." - Mr Node.js Node HTTP module Basic client / server model based loosely off the Python SimpleHTTPServer library Provides minimal functionality to create a web server Effective when writing simple applications Cumbersome when writing complex stuff Get right down to the 'nitty gritty' of things

Slide 9

Slide 9 text

9 HTTP - Basic Example ' u s e s t r i c t ' ; / / N o n e e d f o r N P M i n s t a l l - n a t i v e ! c o n s t h t t p = r e q u i r e ( ' h t t p ' ) ; / / E v e r y t h i n g i n t h e c r e a t e s e r v e r m e t h o d c o n s t s e r v e r = h t t p . c r e a t e S e r v e r ( ( r e q u e s t , r e s p o n s e ) = > { / / R e s p o n s e h e a d e r s ( n o t e c u s t o m X - * h e a d e r s ) r e s p o n s e . w r i t e H e a d ( 2 0 0 , { ' C o n t e n t - T y p e ' : ' a p p l i c a t i o n / j s o n ' , ' X - P o w e r e d - B y ' : ' c o f f e e ' , ' X - H e a v e n - K n o w s ' : M o r r i s s e y . i s M i s e r a b l e N o w ( ) } ) ; / / R e s p o n s e p a y l o a d ( t h e b o d y ) r e s p o n s e . e n d ( J S O N . s t r i n g i f y ( { n a m e : ' J o e N o r m a n ' , a g e : 2 5 , o c c u p a t i o n : ' D e v e l o p e r ' } ) ) ; / / T h e p o r t t o l i s t e n o n } ) . l i s t e n ( 8 0 8 0 ) ;

Slide 10

Slide 10 text

10 Http - some drawbacks Perfect for basic usage; nightmare for anything complex or nontrivial. Lacks native request routing, middle-ware integration (authentication, logging, caching) High entry level for writing servers (need to understand Node.js buffers, MIME types, content encoding, ...) Really not built for complex server applications! Which brings us on to...

Slide 11

Slide 11 text

11 . 1 Express.js "Fast, unopinionated, minimalist web framework for Node.js" Powerful, widely supported framework. Built on top of an existing library called 'connect'. By far the most popular Node.js framework currently in existence. Provides tons of functionality via 'middleware' (plugins), such as routing, authentication, request parsing, etc. First real, serious framework for Node.js that caused an explosion of popularity. Now is part of Node's incubator program Passes control through routes and middleware via 'next'

Slide 12

Slide 12 text

11 . 2 Routing a p p . g e t ( ' / u s e r s ' , ( r e q , r e s ) = > { r e s . s e n d ( ' A l i s t o f u s e r s c a n b e r e t r i e v e d h e r e ! ) ; } ) ; Body parsing c o n s t b o d y P a r s e r = r e q u i r e ( ' b o d y - p a r s e r ' ) ; . . . a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; Serving static content a p p . u s e ( ' / s t a t i c ' , e x p r e s s . s t a t i c ( ' p u b l i c ' ) ) ; / / = > S e t s u p a r o u t e , ' / s t a t i c ' / / t h a t a c t s a s a p a r e n t f o r a l l s u b f o l d e r s ( f r o n t e n d c o n t e n t ! ) / / h t t p : / / l o c a l h o s t : 3 0 0 0 / s t a t i c / c s s / s t y l e . c s s / / h t t p : / / l o c a l h o s t : 3 0 0 0 / s t a t i c / h e l l o . h t m l

Slide 13

Slide 13 text

12 Express - A (very) basic example ' u s e s t r i c t ' ; c o n s t e x p r e s s = r e q u i r e ( ' e x p r e s s ' ) ; / / S e t s u p a n e w i n s t a n c e o f a n e x p r e s s a p p c o n s t a p p = e x p r e s s ( ) ; c o n s t p o r t = p r o c e s s . e n v . p o r t | | 8 0 8 0 ; / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / T H E P O W E R O F C R U U U U U U D ( 8 ) / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / S i m p l i s t i c r o u t i n g ! s y n t a x o f " a p p . m e t h o d " s i g n a t u r e a p p . p o s t ( ' / u s e r s ' , ( r e q , r e s ) = > { r e s . s e n d ( ` U s e r $ { r e q . b o d y . i d } c r e a t e d . ` ) ; } ) ; / / = > C r e a t e a p p . g e t ( ' / u s e r s ' , ( r e q , r e s ) = > { r e s . s e n d ( ' H e l l o W o r l d ! T h i s s h o u l d r e t r i e v e u s e r s ! ' ) ; } ) ; / / = > R e t r i e v e a p p . p u t ( ' / u s e r s / : i d ' , ( r e q , r e s ) = > r e s . s e n d ( ` U s e r $ { r e q . p a r a m s . i d } u p d a t e d . ` ) ) ; / / = > U p d a t e a p p . d e l e t e ( ' / u s e r s / : i d ' , ( r e q , r e s ) = > r e s . s e n d ( ` U s e r $ { r e q . p a r a m s . i d } d e l e t e d . ` ) ) ; / / = > D e l e t e a p p . l i s t e n ( p o r t , ( ) = > c o n s o l e . l o g ( ` S e r v e r l i s t e n i n g o n $ { p o r t } ` ) ) ;

Slide 14

Slide 14 text

13 Express - the cons Surprisingly large footprint for it being minimal. No built-in error handling. YAMS (yet another middleware syndrome). Now is part of Node's incubator program (yes that's also a pro!). Gradually losing support and popularity. Lots of people have moved onto its successor. And the successor is...

Slide 15

Slide 15 text

14 . 1 Koa "Next generation web framework for Node.js" 'Next step' in the express team, who designed it. Tiny footprint in comparison to its predecessor! Provides 'true' middleware cascading in a stack-like manner. Very similar setup to express, so no framework overhead if you're moving from express to koa. Manages this and more through the concept of generators.

Slide 16

Slide 16 text

14 . 2 Generators & Koa - an overview f u n c t i o n * f o o ( ) { y i e l d ' f o o ' ; y i e l d ' b a r ' ; y i e l d ' b a z ' ; } ; The syntax The meaning Allows you to pause and resume execution of your function using the yield keyword a p p . u s e ( f u n c t i o n * ( n e x t ) { c o n s t s t a r t = n e w D a t e ; y i e l d n e x t ; c o n s t m s = n e w D a t e - s t a r t ; t h i s . s e t ( ' X - B r e w - T i m e ' , ` $ { m s } ` ) ; } ) ; a p p . u s e ( f u n c t i o n * ( ) { t h i s . b o d y = ' B r e w c o m p l e t e ! ' ; } ) ; Generators in Koa are used to pass request contexts through middleware layers for processing. What's going on in this code?

Slide 17

Slide 17 text

15 Koa- A (very) basic example ' u s e s t r i c t ' ; c o n s t k o a = r e q u i r e ( ' k o a ' ) ; c o n s t p a r s e = r e q u i r e ( ' c o - b o d y ' ) ; c o n s t r o u t e = r e q u i r e ( ' k o a - r o u t e ' ) ; / / C r e a t i n g a n i n s t a n c e o f a k o a a p p c o n s t a p p = k o a ( ) ; a p p . u s e ( r o u t e . g e t ( ' / u s e r s ' , u s e r s . l i s t ) ) ; a p p . u s e ( r o u t e . p o s t ( ' / u s e r s ' , u s e r s . c r e a t e ) ) ; a p p . u s e ( r o u t e . p u t ( ' / u s e r s / : i d ' , u s e r s . u p d a t e ) ) ; a p p . u s e ( r o u t e . d e l e t e ( ' / u s e r s / : i d ' , u s e r s . d e l e t e ) ) ; a p p . l i s t e n ( 8 0 8 0 , ( ) = > c o n s o l e . l o g ( ' K o a e x a m p l e l i s t e n i n g o n p o r t 8 0 8 0 ' ) ) ; / / W h e r e u s e r s . l i s t / c r e a t e / u p d a t e / d e l e t e a r e g e n e r a t o r f u n c t i o n s / / i . e f u n c t i o n * l i s t ( ) { t h i s . b o d y = y i e l d t h e R e s u l t O f Y o u r D b C a l l ( ) ; } ;

Slide 18

Slide 18 text

16 Koa- the cons EVERYTHING is a plugin for Koa (including serving static content & routing, which were both native in Express). Nowhere near as popular as other contenders (Express, Hapi, ...). Forces developers to understand a difficult concept just to do some basic API creation (Generators). Lack of support for Node versions < 0.12 Which leads us to (definitely not my favourite)...

Slide 19

Slide 19 text

17 . 1 Hapi.js Developed in-house at Walmart Labs, then released open source. Provides a 'configuration over code' design ethic to writing servers and applications. Easiest maintainability for when your applications get complex. Incredible plugin ecosystem for enterprise and production-ready application development. Active community, active change history, active everywhere. 'Battle-tested' on black friday using a seriously small stack 100% code coverage! "A rich framework for building applications and services"

Slide 20

Slide 20 text

17 . 2 Routing s e r v e r . r o u t e ( { m e t h o d : ' G E T ' , p a t h : ' / p i n g ' , h a n d l e r : ( r e q u e s t , r e p l y ) = > { r e p l y ( ' H e l l o , W o r l d ! ' ) ; } } ) ; Serving static content (via inert, which needs registering!) s e r v e r . r o u t e ( { m e t h o d : ' G E T ' , p a t h : ' / h o m e ' , h a n d l e r : { f i l e : ' / p a t h / t o / f i l e / i n d e x . h t m l ' } } ) ;

Slide 21

Slide 21 text

18 A basic Hapi.js example ' u s e s t r i c t ' ; c o n s t H a p i = r e q u i r e ( ' h a p i ' ) ; c o n s t s e r v e r = n e w H a p i . S e r v e r ( ) ; s e r v e r . c o n n e c t i o n ( { p o r t : 3 0 0 0 } ) ; s e r v e r . r o u t e ( [ { m e t h o d : ' G E T ' , p a t h : ' / h e l l o / { n a m e } ' , h a n d l e r : ( r e q u e s t , r e p l y ) = > { r e p l y ( ` H e l l o , $ { e n c o d e U r i C o m p o n e n t ( r e q u e s t . p a r a m s . n a m e ) } ! ` ) ; } } , { m e t h o d : ' P O S T ' , p a t h : ' / u s e r s / { i d } ' , h a n d l e r : ( r e q u e s t , r e p l y ) = > { / / Y o u r b u s i n e s s l o g i c h e r e r e p l y ( ` U s e r , $ { r e q u e s t . p a r a m s . i d } m a d e ! ` ) ; } } ] ) ;

Slide 22

Slide 22 text

19 Hapi - the cons Breaking changes everywhere! Hapi upgrades major versions far too often. Preferred functionality is using the ecosystem's plugins; they're awesome, but limiting. New versions keep cutting out core functionality (such as query parameter parsing - vital for APIs!) And finally...

Slide 23

Slide 23 text

20 Sails.js Traditional, MVC style 'Convention over Code' server framework (adopts heavily from Ruby on Rails). Comes as standard with a native ORM called Waterline, which is database agnostic! Data-driven at its core via 'data modelling and named associations' Native WebSocket support Great generators for all major components of your app Has a configurable asset pipeline (via Grunt) Also has the ability to auto-generate REST APIs (namely the CRUD of it). All driven by commands until you're really wanting to customise it

Slide 24

Slide 24 text

21 Show me the code!

Slide 25

Slide 25 text

22 Sails - the cons As a framework, its slowly dying. Doesn't like you doing custom things (everything is generated for you). Very steep learning curve for when you actually want to tailor it to fit your needs - especially if you haven't used rails before. Number of bugs that have been stale and are yet to be fixed.

Slide 26

Slide 26 text

23 . 1 Conclusion Node comes with a number of dynamic and powerful server frameworks (and has a decent native 'http' module) Express - Most popular, part of incubator node.js pattern, however core developer has left project (there's a need for the incubator!) Koa - 'the next step' for express-like applications, generator learning curve and low(ish) popularity. Hapi - Best for defining large scale & complex APIs down to its 'configuration over code' philosophy. Worst for simple server applications with single business logic calls i.e. a gaming server. Sails / MVC - Fully featured, sluggish patching & core team is effectively dead.

Slide 27

Slide 27 text

23 . 2 Frameworks to look out for & honourable mentions Adonis - (MVC style) Nodal - (more MVC) Loopback - (enterprise, IBM style express!) Flatiron - (core development express style) Feathers - (new and shiny http and websockets framework) Trails - (the next step for Sails?) http://www.adonisjs.com/ http://www.nodaljs.com/ http://loopback.io/ http://flatironjs.org/ http://feathersjs.com/ https://github.com/trailsjs/trails

Slide 28

Slide 28 text

24 Questions? joseph-norman @joemismatch http://joseph-norman.github.io/