SlideShare a Scribd company logo
1 of 48
Download to read offline
node.js
Eine praktische Einführung



      Felix Geisendörfer




                             21.05.2011 (v7)
@felixge

Twitter / GitHub / IRC
Datei Uploads & Umwandlung als Infrastruktur
                Service für Web- & Mobile-Apps.


- The app we run in production
Core Contributor

                                               &

                                      Module Author



              node-mysql                              node-formidable


-   Joined the mailing list in June 26, 2009
-   When I joined there where #24 people
-   First patch in September 2009
-   Now mailing list has > 3400 members
node @ devcon?


Who is doing JavaScript?
Has used node?
Is using node in production (an app that is running this very moment)?
“Easy” and “Scalable” : )

Node makes Hard -> Easy, Easy -> Hard
Node.js
• Gestarted durch Ryan Dahl

• Google’s V8 JavaScript engine (kein DOM)

• Modul System, Dateisystem, Netzwerk, Http und
  Dns
Installing

$ git clone 
git://github.com/joyent/node.git
$ cd node
$ ./configure
$ make install
Ingredients
                          libeio                   libev




             c-ares                                 V8


                                     http_parser
libev: event loop
libeio: async I/O
c-ares: non-blocking dns
http_parser: 40 bytes / connection
v8: google’s JS engine
Serverseitiges JavaScript
Serverseitiges JavaScript

           • Netscape LiveWire (1996)

           • Rhino (1997)

           • 50+ weitere Plattformen

LiveWire to script enterprise appliances

Rhino was done because the plan was to rewrite netscape entirely in Java (Javagator)

Wikipedia lists 50+ other plattform since then
Was war das Problem?

• Langsame Engines

• Wenig Interesse an JavaScript bis ~2005

• Bessere alternativen
Warum JavaScript?
                               3 Gründe




Why not python / ruby / java
#1 - Die Guten Seiten




World’s most misunderstood programming language
Closures
JSON
Flexible
V8 (Chrome)


    SpiderMonkey (Firefox)                     JavaScriptCore (Safari)



                #2 - JS Engine Wars
                 Chakra (IE9)                  Carakan (Opera)



                                                     siehe: arewefastyet.com
War on terror

Spider Monkey: TraceMonkey, JägerMonkey
JavaScriptCore: SquirrelFish Extreme / Nitro
#3 - Kein I/O im core
Non-blocking I/O
Blocking I/O

    var a = db.query('SELECT A');
    console.log('result a:', a);

    var b = db.query('SELECT B');
    console.log('result b:', b);


                             Dauer = SUM(A, B)
Disk / Network access is 1.000-1.000.000 slower than CPU / Ram access
I/O im Verhältnis

• CPU / Ram: Sehr Schnell

• Disk / Netzwerk: 1.000x - 1.000.000x
  langsamer
Non-Blocking I/O
db.query('SELECT A', function(result) {
  console.log('result a:', result);
});

db.query('SELECT B', function(result) {
  console.log('result b:', result);
});

            Dauer = MAX(A, B)
Non-Blocking I/O

• I/O Aufgaben an den Kernel weitergeben
  und events durch file descriptor polling
  erkannt (select, epoll, kqueue, etc.)


• Thread pool für alles andere
Single Threaded
var a = [];
function first() {
  a.push(1);
  a.push(2);
}

function second() {
  a.push(3);
  a.push(4);
}

setTimeout(first, 10);
setTimeout(second, 10);
Single Threaded
    var a = [];
    function first() {
      a.push(1);                  • [1, 2, 3, 4] ?
      a.push(2);
    }
                                  • [3, 4, 1, 2] ?
    function second() {
      a.push(3);
      a.push(4);                  • [1, 3, 2, 4] ?
    }

    setTimeout(first, 10);
                                  • BAD_ACCESS ?
    setTimeout(second, 10);
Who thinks:

-   Answer not on the list?
-   A possible?
-   B possible?
-   C possible?
Single Threaded
    var a = [];
    function first() {
      a.push(1);                  • [1, 2, 3, 4]
      a.push(2);
    }
                                  • [3, 4, 1, 2]
    function second() {
      a.push(3);
      a.push(4);                  • [1, 3, 2, 4]
    }

    setTimeout(first, 10);
                                  • BAD_ACCESS
    setTimeout(second, 10);
Who thinks:

-   Answer not on the list?
-   A possible?
-   B possible?
-   C possible?
Anwendungsbereiche
DIRT

          • Data Intensive

          • Real Time


Daten verlieren = schlecht
Daten verzögern = noch schlechter
Beispiele (DIRT)

• Chat Server

• Twitter

• Telephony
Andere Beispiele

          • Single Page Apps

          • File uploads

          • Unix tools parallel laufen lassen

http://teddziuba.com/2011/02/the-case-against-queues.html

“I love asynchronous stuff as much as the next guy, but think of a queue like Java: it
encourages large swaths of mediocre programmers to overengineer shit, and it keeps
systems administrators in business by giving them something to respond to at 4AM.” -- Ted
Dziuba
Interessante Projekte
Package management
2000+ Module in npm
      +10 neue / Tag
Web Frameworks

• Express.js (Sinatra clone)

• Fab.js (Mind-bending & awesome)
Socket.IO
var http = require('http');
var io = require('socket.io');

var server = http.createServer();
server.listen(80);

var socket = io.listen(server);
socket.on('connection', function(client){
  client.send('hi');

  client.on('message', function(){ … })
  client.on('disconnect', function(){ … })
});


                 Server
Socket.IO

<script src="http://{node_server_url}/socket.io/socket.io.js" />
<script>
  var socket = new io.Socket({node_server_url});
  socket.connect();
  socket.on('connect', function(){ … })
  socket.on('message', function(){ … })
  socket.on('disconnect', function(){ … })
</script>




                             Client
Socket.IO
       •   WebSocket

       •   Adobe® Flash® Socket

       •   AJAX long polling

       •   AJAX multipart streaming

       •   Forever Iframe

       •   JSONP Polling

Chooses most capable transport at runtime!
Ready for production?
Unsere Erfahrungen
                         mit transloadit.com

• Über 200.000 Datei Uploads

• Mehrere TB an Daten verarbeitet

• Keine bugs, Memory usage 30 - 80 MB
Community
Benevolent Dictator For Life




                                    Ryan Dahl
Wohlwollender Diktator auf Lebenszeit
Community

          • Mailing list (nodejs, nodejs-dev)

          • IRC (#node.js) - 500+ User online


4000+ people on mailing list
500+ people on IRC
Hosting
Probleme
db.query('SELECT A', function() {
  db.query('SELECT B', function() {
    db.query('SELECT C', function() {
      db.query('SELECT D', function() {
        // WTF
      });
    });
  });
});
Probleme
          • Stack traces gehen an der event loop
              Grenze verloren


          • Aufgaben auf mehrere Prozesse verteilen

          • V8: 1- 1.9 GB heap limit / GC Probleme

+ not as many libraries as the ruby ecosystem
Questions?
Mehr Infos


nodeguide.com
       /

nodebeginner.org
Node.js Workshop in Köln

           Freitag, 10. Juni

nodecologne.eventbrite.com

   15% Discount mit code ‘devcon’
Questions?

More Related Content

More from Felix Geisendörfer

More from Felix Geisendörfer (10)

How to Test Asynchronous Code
How to Test Asynchronous CodeHow to Test Asynchronous Code
How to Test Asynchronous Code
 
Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)
 
Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?
 
Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)
 
Node.js in production
Node.js in productionNode.js in production
Node.js in production
 
Nodejs - A-quick-tour-v3
Nodejs - A-quick-tour-v3Nodejs - A-quick-tour-v3
Nodejs - A-quick-tour-v3
 
Dirty - How simple is your database?
Dirty - How simple is your database?Dirty - How simple is your database?
Dirty - How simple is your database?
 
With jQuery & CakePHP to World Domination
With jQuery & CakePHP to World DominationWith jQuery & CakePHP to World Domination
With jQuery & CakePHP to World Domination
 
ActiveDOM
ActiveDOMActiveDOM
ActiveDOM
 

Recently uploaded

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 

Recently uploaded (20)

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 

Node.js - Eine praktische Einführung (v7)

  • 1. node.js Eine praktische Einführung Felix Geisendörfer 21.05.2011 (v7)
  • 3. Datei Uploads & Umwandlung als Infrastruktur Service für Web- & Mobile-Apps. - The app we run in production
  • 4. Core Contributor & Module Author node-mysql node-formidable - Joined the mailing list in June 26, 2009 - When I joined there where #24 people - First patch in September 2009 - Now mailing list has > 3400 members
  • 5. node @ devcon? Who is doing JavaScript? Has used node? Is using node in production (an app that is running this very moment)?
  • 6. “Easy” and “Scalable” : ) Node makes Hard -> Easy, Easy -> Hard
  • 7. Node.js • Gestarted durch Ryan Dahl • Google’s V8 JavaScript engine (kein DOM) • Modul System, Dateisystem, Netzwerk, Http und Dns
  • 8. Installing $ git clone git://github.com/joyent/node.git $ cd node $ ./configure $ make install
  • 9. Ingredients libeio libev c-ares V8 http_parser libev: event loop libeio: async I/O c-ares: non-blocking dns http_parser: 40 bytes / connection v8: google’s JS engine
  • 11. Serverseitiges JavaScript • Netscape LiveWire (1996) • Rhino (1997) • 50+ weitere Plattformen LiveWire to script enterprise appliances Rhino was done because the plan was to rewrite netscape entirely in Java (Javagator) Wikipedia lists 50+ other plattform since then
  • 12. Was war das Problem? • Langsame Engines • Wenig Interesse an JavaScript bis ~2005 • Bessere alternativen
  • 13. Warum JavaScript? 3 Gründe Why not python / ruby / java
  • 14. #1 - Die Guten Seiten World’s most misunderstood programming language Closures JSON Flexible
  • 15. V8 (Chrome) SpiderMonkey (Firefox) JavaScriptCore (Safari) #2 - JS Engine Wars Chakra (IE9) Carakan (Opera) siehe: arewefastyet.com War on terror Spider Monkey: TraceMonkey, JägerMonkey JavaScriptCore: SquirrelFish Extreme / Nitro
  • 16. #3 - Kein I/O im core
  • 18. Blocking I/O var a = db.query('SELECT A'); console.log('result a:', a); var b = db.query('SELECT B'); console.log('result b:', b); Dauer = SUM(A, B) Disk / Network access is 1.000-1.000.000 slower than CPU / Ram access
  • 19. I/O im Verhältnis • CPU / Ram: Sehr Schnell • Disk / Netzwerk: 1.000x - 1.000.000x langsamer
  • 20. Non-Blocking I/O db.query('SELECT A', function(result) { console.log('result a:', result); }); db.query('SELECT B', function(result) { console.log('result b:', result); }); Dauer = MAX(A, B)
  • 21. Non-Blocking I/O • I/O Aufgaben an den Kernel weitergeben und events durch file descriptor polling erkannt (select, epoll, kqueue, etc.) • Thread pool für alles andere
  • 22. Single Threaded var a = []; function first() { a.push(1); a.push(2); } function second() { a.push(3); a.push(4); } setTimeout(first, 10); setTimeout(second, 10);
  • 23. Single Threaded var a = []; function first() { a.push(1); • [1, 2, 3, 4] ? a.push(2); } • [3, 4, 1, 2] ? function second() { a.push(3); a.push(4); • [1, 3, 2, 4] ? } setTimeout(first, 10); • BAD_ACCESS ? setTimeout(second, 10); Who thinks: - Answer not on the list? - A possible? - B possible? - C possible?
  • 24. Single Threaded var a = []; function first() { a.push(1); • [1, 2, 3, 4] a.push(2); } • [3, 4, 1, 2] function second() { a.push(3); a.push(4); • [1, 3, 2, 4] } setTimeout(first, 10); • BAD_ACCESS setTimeout(second, 10); Who thinks: - Answer not on the list? - A possible? - B possible? - C possible?
  • 26. DIRT • Data Intensive • Real Time Daten verlieren = schlecht Daten verzögern = noch schlechter
  • 27. Beispiele (DIRT) • Chat Server • Twitter • Telephony
  • 28. Andere Beispiele • Single Page Apps • File uploads • Unix tools parallel laufen lassen http://teddziuba.com/2011/02/the-case-against-queues.html “I love asynchronous stuff as much as the next guy, but think of a queue like Java: it encourages large swaths of mediocre programmers to overengineer shit, and it keeps systems administrators in business by giving them something to respond to at 4AM.” -- Ted Dziuba
  • 31. 2000+ Module in npm +10 neue / Tag
  • 32. Web Frameworks • Express.js (Sinatra clone) • Fab.js (Mind-bending & awesome)
  • 33. Socket.IO var http = require('http'); var io = require('socket.io'); var server = http.createServer(); server.listen(80); var socket = io.listen(server); socket.on('connection', function(client){ client.send('hi'); client.on('message', function(){ … }) client.on('disconnect', function(){ … }) }); Server
  • 34. Socket.IO <script src="http://{node_server_url}/socket.io/socket.io.js" /> <script> var socket = new io.Socket({node_server_url}); socket.connect(); socket.on('connect', function(){ … }) socket.on('message', function(){ … }) socket.on('disconnect', function(){ … }) </script> Client
  • 35. Socket.IO • WebSocket • Adobe® Flash® Socket • AJAX long polling • AJAX multipart streaming • Forever Iframe • JSONP Polling Chooses most capable transport at runtime!
  • 37. Unsere Erfahrungen mit transloadit.com • Über 200.000 Datei Uploads • Mehrere TB an Daten verarbeitet • Keine bugs, Memory usage 30 - 80 MB
  • 39. Benevolent Dictator For Life Ryan Dahl Wohlwollender Diktator auf Lebenszeit
  • 40. Community • Mailing list (nodejs, nodejs-dev) • IRC (#node.js) - 500+ User online 4000+ people on mailing list 500+ people on IRC
  • 43. db.query('SELECT A', function() { db.query('SELECT B', function() { db.query('SELECT C', function() { db.query('SELECT D', function() { // WTF }); }); }); });
  • 44. Probleme • Stack traces gehen an der event loop Grenze verloren • Aufgaben auf mehrere Prozesse verteilen • V8: 1- 1.9 GB heap limit / GC Probleme + not as many libraries as the ruby ecosystem
  • 46. Mehr Infos nodeguide.com / nodebeginner.org
  • 47. Node.js Workshop in Köln Freitag, 10. Juni nodecologne.eventbrite.com 15% Discount mit code ‘devcon’