Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Illustrated Guide to Node.js - KCDC 2023

The Illustrated Guide to Node.js - KCDC 2023

Node.js is a compelling platform for building all types of applications for startups to enterprises. Node.js strategically unites developers through the universal language of JavaScript. Or TypeScript! Why should you learn Node.js, and where do you start?

You will walk away from this fun introduction to Node.js having learned its strengths and the tools you need to be productive. We will cover a typical workflow of creating and debugging a web application. We'll also look at popular frameworks, libraries, and learning resources to give you the best start.

David Neal

June 22, 2023
Tweet

More Decks by David Neal

Other Decks in Technology

Transcript

  1. Why Node.js? • Rapid innovation & delivery • Developer happiness

    • Attract & retain talent • Performance “Why Node.js is Becoming the Go-To Technology in the Enterprise” – nearform.com
  2. • Backend API for SPAs, Mobile apps, etc. • “Serverless”

    computing • Real-time, streaming • WebSockets, push notifications • Chat, IM, social media Node.js Use Cases
  3. More than just backend • Automation Scripts (DevOps) • CLI

    tools (compile with nexe) • Microservices • Internet of Things • Desktop Apps
  4. Install Node.js with NVM Mac or Linux? Use nvm! https://github.com/nvm-sh/nvm

    Windows? Install Windows Subsytem for Linux (WSL)! > nvm install 18
  5. First Things First! > mkdir myproject > cd myproject >

    npm init This utility will walk you through creating a package.json file...
  6. Install Dependencies > npm install axios > npm install --save-dev

    eslint > npm install -D eslint-config-reverentgeek
  7. const fs = require( "fs" ); // Built-in Node.js module

    const express = require( "express" ); // Module installed via npm const ApiService = require( "./app/ApiService" ); // Local module const api = new ApiService( { port: 8888 } ); module-examples.js
  8. const fs = require( "fs" ); // Built-in Node.js module

    const express = require( "express" ); // Module installed via npm const ApiService = require( "./app/ApiService" ); // Local module const api = new ApiService( { port: 8888 } ); module-examples.js
  9. const fs = require( "fs" ); // Built-in Node.js module

    const express = require( "express" ); // Module installed via npm const ApiService = require( "./app/ApiService" ); // Local module const api = new ApiService( { port: 8888 } ); module-examples.js
  10. const fs = require( "fs" ); // Built-in Node.js module

    const express = require( "express" ); // Module installed via npm const ApiService = require( "./app/ApiService" ); // Local module const api = new ApiService( { port: 8888 } ); module-examples.js
  11. const fs = require( "fs" ); // Built-in Node.js module

    const express = require( "express" ); // Module installed via npm const ApiService = require( "./app/ApiService" ); // Local module const api = new ApiService( { port: 8888 } ); module-examples.js
  12. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { // Do something with the error console.log( err ); return; } // Do stuff with results for ( let i = 0; i < results.length; i++ ) { // stuff... } } ); callback-example.js
  13. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { // Do something with the error console.log( err ); return; } // Do stuff with results for ( let i = 0; i < results.length; i++ ) { // stuff... } } ); callback-example.js
  14. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { // Do something with the error console.log( err ); return; } // Do stuff with results for ( let i = 0; i < results.length; i++ ) { // stuff... } } ); callback-example.js
  15. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results => { for ( let i = 0; i < results.length; i++ ) { // stuff... } } ) .catch( err => { console.log( err ); } ); promise-example.js
  16. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results => { for ( let i = 0; i < results.length; i++ ) { // stuff... } } ) .catch( err => { console.log( err ); } ); promise-example.js
  17. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results => { for ( let i = 0; i < results.length; i++ ) { // stuff... } } ) .catch( err => { console.log( err ); } ); promise-example.js
  18. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results => { for ( let i = 0; i < results.length; i++ ) { // stuff... } } ) .catch( err => { console.log( err ); } ); promise-example.js
  19. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i++ ) { // stuff... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js
  20. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i++ ) { // stuff... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js
  21. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i++ ) { // stuff... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js
  22. const ApiService = require( "./app/ApiService" ); const api = new

    ApiService( { port: 8888 } ); // Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i++ ) { // stuff... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js
  23. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js
  24. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js
  25. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js
  26. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js
  27. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); // output: 100 C is 212 F temp-example.js
  28. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); // output: 100 C is 212 F temp-example.js
  29. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); // output: 100 C is 212 F temp-example.js
  30. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); // output: 100 C is 212 F temp-example.js
  31. function convertToCelsius( f ) { return ( f - 32

    ) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); // output: 100 C is 212 F temp-example.js
  32. import { readFile } from "node:fs/promises"; export async function readFileJson(

    fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js
  33. import { readFile } from "node:fs/promises"; export async function readFileJson(

    fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js
  34. import { readFile } from "node:fs/promises"; export async function readFileJson(

    fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js
  35. esm-module-example.js import { readFile } from "node:fs/promises"; export async function

    readFileJson( fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-example.js import { readFileJson } from "./esm-module-example.mjs"; const baconFile = new URL( "./bacon.json", import.meta.url ); const bacon = await readFileJson( baconFile ); console.log( bacon );
  36. esm-module-example.js import { readFile } from "node:fs/promises"; export async function

    readFileJson( fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-example.js import { readFileJson } from "./esm-module-example.mjs"; const baconFile = new URL( "./bacon.json", import.meta.url ); const bacon = await readFileJson( baconFile ); console.log( bacon );
  37. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  38. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  39. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  40. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  41. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  42. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  43. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  44. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { // log error } } sql-example.js
  45. const sql = require( "mssql" ); // Read from environment

    variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { ... } module.exports = { getAccountByEmail }; sql-example.js
  46. Developer tools Package(s) Description eslint lint and format rules for

    JavaScript nodemon automatically restarts in dev node:test, jest, mocha test frameworks testdouble, sinon spies, stubs, mocks
  47. Recommended tools Package(s) Description dotenv loads environment variables from a

    .env file fs-extra adds convenient extensions to file system fetch, axios, or got http clients socket.io sockets, real-time commander command-line argument library for building CLIs nexe compile app to a standalone executable
  48. Integration Strategies • Node.js as proxy, use http client •

    nginx • Messaging (e.g. RabbitMQ, ZeroMQ Azure Service Bus)