Slide 1

Slide 1 text

NODE.JS SERVER SIDE JAVASCRIPT By Grégoire Charvet Slides on and github speaker deck

Slide 2

Slide 2 text

ABOUT ME Full time node.js dev at Digbil Web dev for the past 2.5 years (front end and back end)

Slide 3

Slide 3 text

NODE.JS: WHAT'S THAT?

Slide 4

Slide 4 text

SERVER SIDE JAVASCRIPT

Slide 5

Slide 5 text

IN DETAILS V8 javascript engine Node.js API replaces the DOM & browser API An event loop

Slide 6

Slide 6 text

V8 ENGINE Controlled javascript env (es5) Some es6 features present in 0 . 1 1 (use - - h a r m o n y )

Slide 7

Slide 7 text

NODE.JS API Core api to access the file system, the network (http, sockets), crypto functions... No DOM More about the core api later

Slide 8

Slide 8 text

EVENT LOOP Same as in the browsers. Event driven system New functions s e t I m m e d i a t e and p r o c e s s . n e x t T i c k Fundamental concept in node.js (watch: ) What the heck is the event loop anyway

Slide 9

Slide 9 text

MODULE SYSTEM

Slide 10

Slide 10 text

COMMONJS Synchronous r e q u i r e Expose API with m o d u l e . e x p o r t s

Slide 11

Slide 11 text

EXPOSING STUFF In a file: a c t o r . j s f u n c t i o n A c t o r ( ) { t h i s . n a m e = ' B r a d P i t t ' } A c t o r . p r o t o t y p e . g e t N a m e = f u n c t i o n ( ) { r e t u r n t h i s . n a m e ; } m o d u l e . e x p o r t s . A c t o r = A c t o r ;

Slide 12

Slide 12 text

GETTING STUFF FROM OTHER PLACES In a file: m a i n . j s v a r A c t o r = r e q u i r e ( ' . / a c t o r ' ) . A c t o r ; Synchronous call Relative path (. . / works too) . j s can be omitted

Slide 13

Slide 13 text

EXTERNAL OR NATIVE MODULES Requiring an external module (see: p a c k a g e . j s o n later on) Will look up the module in n o d e _ m o d u l e s folder. v a r e x p r e s s = r e q u i r e ( ' e x p r e s s ' ) ; / / n o ` . / ` h e r e v a r c r y p t o = r e q u i r e ( ' c r y p t o ' ) ; / / n a t i v e n o d e . j s a p i

Slide 14

Slide 14 text

SYNC VS ASYNC CALLBACK CONVENTION (CONTINUATION)

Slide 15

Slide 15 text

A SYNCHRONOUS EXAMPLE Read a file / / n a t i v e n o d e m o d u l e t o a c c e s s t h e f i l e s y s t e m v a r f s = r e q u i r e ( ' f s ' ) ; t r y { v a r f i l e C o n t e n t = f s . r e a d F i l e S y n c ( ' . / m y F i l e . t x t ' ) ; } c a t c h ( e r r ) { c o n s o l e . l o g ( ' E r r o r w h i l e r e a d i n g f i l e : ' , e r r ) ; } ONE MAJOR CAVEAT Blocking code (and there is only one thread)

Slide 16

Slide 16 text

USE ASYNC CODE IN NODE That's how it works Most api don't have synchronous equivalent

Slide 17

Slide 17 text

HOW? v a r f s = r e q u i r e ( ' f s ' ) ; f s . r e a d F i l e ( ' . / m y F i l e . t x t ' , f u n c t i o n c a l l b a c k ( e r r , f i l e ) { i f ( e r r ) { c o n s o l e . l o g ( ' G o t a n e r r o r : ' , e r r ) ; } e l s e { c o n s o l e . l o g ( ' G o t f i l e h e r e ' ) ; } } ) ;

Slide 18

Slide 18 text

ASYNC? v a r f s = r e q u i r e ( ' f s ' ) ; c o n s o l e . l o g ( ' a b o u t t o r e a d f i l e ' ) ; v a r r e s u l t = f s . r e a d F i l e ( ' . / m y F i l e . t x t ' , f u n c t i o n ( e r r , f i l e ) { i f ( e r r ) c o n s o l e . l o g ( ' e r r o r : ' , e r r ) ; e l s e c o n s o l e . l o g ( ' g o t f i l e ' ) ; } ) ; c o n s o l e . l o g ( ' d o n e r e a d i n g f i l e ? ' ) ; c o n s o l e . l o g ( ' r e s u l t : ' , r e s u l t ) ; Execution result: "about to read file" "done reading file" "result: undefined" "got file" (some time later)

Slide 19

Slide 19 text

ERROR HANDLING t r y { s e t T i m e o u t ( f u n c t i o n ( ) { / / a n o t h e r a s y n c f u n c t i o n t h r o w n e w E r r o r ( ' c a t c h m e i f y o u c a n ' ) ; } , 0 ) ; } c a t c h ( e r r ) { c o n s o l e . l o g ( ' G o t y o u : ' , e r r ) ; } Result: * Error: catch me if you can at null._onTimeout (/home/greg/tests/error.js:2:9) at Timer.listOnTimeout (timers.js:133:15) (process crashed)

Slide 20

Slide 20 text

CALLBACK CONVENTION f u n c t i o n c a l l b a c k ( e r r , a r g 1 , a r g 2 , a r g s . . . ) { / / e r r o r o b j e c t i s a l w a y s t h e f i r s t a r g u m e n t } d o S o m e t h i n g A s y n c ( ' f o o ' , ' b a r ' , ' b a z ' , c a l l b a c k ) ; / / t h e c a l l b a c k f u n c t i o n i s a l w a y s t h e l a s t a r g u m e n t All node.js ecosystem uses this convention

Slide 21

Slide 21 text

IMPLICATIONS No return values Need to pass callbacks for async operations Don't throw error Uncaught errors will CRASH the whole program (process.on('uncaughtException', handler));

Slide 22

Slide 22 text

WHO CALLS MY CALLBACK??? The event loop is here for that

Slide 23

Slide 23 text

INTERNALS v a r f s = r e q u i r e ( ' f s ' ) ; f s . r e a d F i l e ( ' . / m y F i l e . t x t ' , f u n c t i o n c a l l b a c k ( e r r , f i l e ) { i f ( e r r ) { c o n s o l e . l o g ( ' G o t a n e r r o r : ' , e r r ) ; } e l s e { c o n s o l e . l o g ( ' G o t f i l e h e r e ' ) ; } } ) ; Call the readFile function from node API And register the callback with readFile Do nothing in the main thread When readFile finishes, put the callback in the event loop If no js code is running at that point execute the callback (Otherwise, finish execution of code and execute first handler in the event loop)

Slide 24

Slide 24 text

OTHER ASYNC CONSTRUCTIONS (ADVANCED) Promises (es6) Generators (es6) Async functions (es7)

Slide 25

Slide 25 text

PACKAGE.JSON AND NPM { " n a m e " : " r e v e a l . j s " , " v e r s i o n " : " 2 . 6 . 2 " , " d e s c r i p t i o n " : " T h e H T M L P r e s e n t a t i o n F r a m e w o r k " , " h o m e p a g e " : " h t t p : / / l a b . h a k i m . s e / r e v e a l - j s " , " s u b d o m a i n " : " r e v e a l j s " , " s c r i p t s " : { " t e s t " : " g r u n t t e s t " , " s t a r t " : " " } , " a u t h o r " : { " n a m e " : " H a k i m E l H a t t a b " , " e m a i l " : " h a k i m . e l h a t t a b @ g m a i l . c o m " , " w e b " : " h t t p : / / h a k i m . s e " } , " r e p o s i t o r y " : { " t y p e " : " g i t " , " u r l " : " g i t : / / g i t h u b . c o m / h a k i m e l / r e v e a l . j s . g i t " } , " e n g i n e s " : { " n o d e " : " ~ 0 . 8 . 0 " } , " d e p e n d e n c i e s " : { " u n d e r s c o r e " : " ~ 1 . 5 . 1 " , " e x p r e s s " : " ~ 2 . 5 . 9 " , " m u s t a c h e " : " ~ 0 . 7 . 2 " , " s o c k e t . i o " : " ~ 0 . 9 . 1 3 " } ,

Slide 26

Slide 26 text

SIGNATURE OF NODE.JS PROJECTS

Slide 27

Slide 27 text

GENERAL INFO { " n a m e " : " m y P a c k a g e N a m e " , " d e s c r i p t i o n " : " t h i s i s a v e r y u s e f u l d e s c r i p t i o n " , " h o m e p a g e " : " h t t p : / / f o o b a r . c o m " }

Slide 28

Slide 28 text

VERSION { " v e r s i o n " : " 2 . 4 . 8 " } Uses s e m a n t i c v e r s i o n i n g

Slide 29

Slide 29 text

SEMANTIC VERSIONING (SEMVER) Version follow the pattern x . y . z

Slide 30

Slide 30 text

X.Y.Z Bugfix version Only minor changes and bug fixes x . y . z 1 and x . y . z 2 must be compatible Automatic upgrade

Slide 31

Slide 31 text

X.Y.Z Minor version Can introduce new features Usually preserves backward compatibility Usually painless upgrades

Slide 32

Slide 32 text

X.Y.Z Major version Reserved for breaking changes (new API) Should provide an upgrade guide

Slide 33

Slide 33 text

REPO AND ENGINE { " r e p o s i t o r y " : { " t y p e " : " g i t " , " u r l " : " g i t : / / g i t h u b . c o m / h a k i m e l / r e v e a l . j s . g i t " } , " e n g i n e s " : { " n o d e " : " ~ 0 . 8 . 0 " } }

Slide 34

Slide 34 text

LICENSE { " l i c e n s e s " : [ { " t y p e " : " M I T " , " u r l " : " h t t p s : / / g i t h u b . c o m / h a k i m e l / r e v e a l . j s / b l o b / m a s t e r / L I C E N S E " } ] }

Slide 35

Slide 35 text

DEPENDENCIES { " d e p e n d e n c i e s " : { " u n d e r s c o r e " : " ~ 1 . 5 . 1 " , " e x p r e s s " : " ~ 2 . 5 . 9 " , " m u s t a c h e " : " ~ 0 . 7 . 2 " , " s o c k e t . i o " : " ~ 0 . 9 . 1 3 " } } Uses to parse Picked up by n p m i n s t a l l Installed under < r o o t D i r > / n o d e _ m o d u l e s / node semver

Slide 36

Slide 36 text

MAIN { " m a i n " : " l i b / i n d e x . j s " } Entry point of your package

Slide 37

Slide 37 text

SCRIPTS { " s c r i p t s " : { " t e s t " : " m o c h a - - b a i l t e s t / " , " s t a r t " : " n o d e l i b / s e r v e r . j s " , " p o s t i n s t a l l " : " n o d e n o d e _ m o d u l e s / . b i n / b o w e r i n s t a l l " } } Define script to be run with n p m r u n < s c r i p t n a m e > Some predefine scripts: n p m t e s t n p m s t a r t p o s t i n s t a l l automatically run after n p m i n s t a l l

Slide 38

Slide 38 text

MORE d e v D e p e n d e n c i e s , p e e r D e p e n d e n c i e s c o n t r i b u t o r s Full doc

Slide 39

Slide 39 text

NPM Stands for "Node Package Manager" Bundled with node Allow installation of dependency and compilation Some issues on windows dependency tree run too deep Sometimes native compilation is an issue

Slide 40

Slide 40 text

WEB SERVERS

Slide 41

Slide 41 text

Node is very strong for IO bound program. Native h t t p (and h t t p s ) module to create web servers. Very barebone api -> needs for some libraries/framework. Shines when there is a lot of quiet connections

Slide 42

Slide 42 text

EXAMPLE OF A WEBSERVER A webserver in 11 lines. v a r h t t p = r e q u i r e ( ' h t t p ' ) ; f u n c t i o n r e q u e s t H a n d l e r ( r e q , r e s ) { r e s . s t a t u s C o d e = 2 0 0 ; r e s . e n d ( ' H e l l o ' ) ; } v a r 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 H a n d l e r ) ; v a r p o r t = 8 0 0 0 ; s e r v e r . l i s t e n ( p o r t , f u n c t i o n ( e r r ) { i f ( e r r ) c o n s o l e . e r r o r ( ' E r r o r w h e n s t a r t i n g s e r v e r : ' , e r r ) ; e l s e c o n s o l e . l o g ( ' S e r v e r s t a r t e d o n p o r t % d ' , p o r t ) ; } ) ;

Slide 43

Slide 43 text

PITFALL Only one thread for your code: beware of processing time! f u n c t i o n f i b o ( n ) { r e t u r n n < 2 ? 1 : f i b o ( n - 1 ) + f i b o ( n - 2 ) ; } f u n c t i o n r e q u e s t H a n d l e r ( r e q , r e s ) { r e s . e n d ( S t r i n g ( f i b o ( 4 2 ) ) ) ; } a b - n 1 0 - c 1 0 h t t p : / / l o c a l h o s t : 8 0 0 0 / R e q u e s t s p e r s e c o n d : 0 . 2 8 [ # / s e c ] ( m e a n )

Slide 44

Slide 44 text

BARE BONE CORE API No routing (different handler for / f o o and / b a r ) No body parsing (stuff send with m u l t i p a r t - f o r m - d a t a or x - w w w - f o r m - u r l e n c o d e d No cookie support (need to parse them manually from the headers)

Slide 45

Slide 45 text

WEB LIB/FRAMEWORK Express - by far the most popular one Restify - if you're only interested in API Koa - uses generators Kraken (paypal) Sails Loopback (see next talk) Waigo (koa based)

Slide 46

Slide 46 text

THE MOST POPULAR ONE: EXPRESS v a r a p p = r e q u i r e ( ' e x p r e s s ' ) ( ) ; a p p . g e t ( ' / ' , f u n c t i o n ( r e q , r e s ) { r e s . s e n d ( ' H e l l o ' ) ; } ) ; a p p . g e t ( ' / p i n g ' , f u n c t i o n ( r e q , r e s ) { r e s . s e n d ( ' p o n g ' ) ; } ) ; a p p . g e t ( ' * ' , f u n c t i o n ( r e q , r e s ) { r e s . s t a t u s ( 4 0 4 ) . s e n d ( ' F o u r O h F o u r ' ) ; } ) ; a p p . l i s t e n ( 8 0 0 0 ) ;

Slide 47

Slide 47 text

EXPRESS' MIDDLEWARES Handlers executed for each requests for a matching path Do some processing/logic Give back the control to the next handler

Slide 48

Slide 48 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; a p p . u s e ( m u l t i p a r t ( ) ) ; a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; a p p . u s e ( c s u r f ( ) ) ; a p p . u s e ( c o m p r e s s i o n ( ) ) ;

Slide 49

Slide 49 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; / / d e c o d e r e q u e s t ' s b o d y a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; / / s a m e f o r j s o n a p p . u s e ( m u l t i p a r t ( ) ) ; a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; a p p . u s e ( c s u r f ( ) ) ; a p p . u s e ( c o m p r e s s i o n ( ) ) ;

Slide 50

Slide 50 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; a p p . u s e ( m u l t i p a r t ( ) ) ; / / h a n d l e f i l e s a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; a p p . u s e ( c s u r f ( ) ) ; a p p . u s e ( c o m p r e s s i o n ( ) ) ;

Slide 51

Slide 51 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; a p p . u s e ( m u l t i p a r t ( ) ) ; a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; / / h a n d l e c o o k i e a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; / / s e s s i o n s a p p . u s e ( c s u r f ( ) ) ; a p p . u s e ( c o m p r e s s i o n ( ) ) ;

Slide 52

Slide 52 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; a p p . u s e ( m u l t i p a r t ( ) ) ; a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; a p p . u s e ( c s u r f ( ) ) ; / / C S R F p r o t e c t i o n a p p . u s e ( c o m p r e s s i o n ( ) ) ;

Slide 53

Slide 53 text

TYPICAL EXPRESS APP v a r a p p = e x p r e s s ( ) ; a p p . u s e ( b o d y P a r s e r . u r l E n c o d e d ( ) ) ; a p p . u s e ( b o d y P a r s e r . j s o n ( ) ) ; a p p . u s e ( m u l t i p a r t ( ) ) ; a p p . u s e ( c o o k i e - p a r s e r ( ) ) ; a p p . u s e ( c o o k i e - s e s s i o n ( ) ) ; a p p . u s e ( c s u r f ( ) ) ; a p p . u s e ( c o m p r e s s i o n ( ) ) ; / / g z i p c o m p r e s s i o n

Slide 54

Slide 54 text

CLOSING THOUGHTS

Slide 55

Slide 55 text

NODE.JS SPECIFIC APIS Buffers (b u f . r e a d U I n t 1 6 L E ), low level byte manipulation Streams, similar to unix steams (can be piped) Crypto (some system dependencies like openssl) Child processes and cluster File system, path & Os Net (low level networking, unix socket manipulation)

Slide 56

Slide 56 text

ECOSYSTEM

Slide 57

Slide 57 text

ECOSYSTEM All based on github, open sourced Write small modules, and compose them together One module should do one thing only, but well (unix philosophy) Virtually anything already exist

Slide 58

Slide 58 text

CONSIDERATIONS WHEN USING NODE.JS Great for IO bound systems. Same language as the front-end: isomorphic application (meteor). One thread: suck to do any kind of processing. It's javascript: great for prototyping, requires rigor when growing.

Slide 59

Slide 59 text

RESOURCES (video) Node.js docs npm & package.json 9 anti patterns for node.js teams Stream adventures

Slide 60

Slide 60 text

WE'RE HIRING Interested to write node.js full time ? Production application Globally distributed (aws) Contact me: [email protected]

Slide 61

Slide 61 text

Q&A