{"id":60,"date":"2016-03-21T01:31:35","date_gmt":"2016-03-21T00:31:35","guid":{"rendered":"http:\/\/brozanski.net\/?p=60"},"modified":"2016-03-21T01:34:00","modified_gmt":"2016-03-21T00:34:00","slug":"moj-pierwszy-serwer-http-w-node-js","status":"publish","type":"post","link":"https:\/\/brozanski.net\/index.php\/2016\/03\/21\/moj-pierwszy-serwer-http-w-node-js\/","title":{"rendered":"M\u00f3j pierwszy serwer HTTP w Node.JS"},"content":{"rendered":"<p>Zapewne jak wi\u0119kszo\u015b\u0107 z deweloper\u00f3w backend&#8217;owych j\u0119zyk JavaScript kojarzy mi si\u0119 z tworzeniem raczej frontendu&#8217;u. Nie lubimy go, bo&#8230; jest inny. Pisz\u0105c skrypty dla UI cz\u0119sto spotyka\u0142em si\u0119 z sytuacj\u0105, \u017ce co\u015b nie dzia\u0142a i nie wiedzia\u0142em dlaczego. Sprawy nie u\u0142atwia\u0142 brak wsparcia dla debugowania, przynajmniej do czasu, a\u017c zacz\u0105\u0142em wykorzystywa\u0107 odpowiednie dodatki do przegl\u0105darek.<br \/>\n<!--more--><\/p>\n<p>Postanowi\u0142em jednak bardziej zaprzyja\u017ani\u0107 si\u0119 z tym j\u0119zykiem i po kilku tygodniach obcowania musz\u0119 powiedzie\u0107, \u017ce bardzo mi si\u0119 podoba. Aktualnie JavaScript jest bardzo rozwini\u0119t\u0105 platform\u0105 do wytwarzania aplikacji i wspiera to zadanie na ka\u017cdym etapie &#8211; od bazy danych, przez serwer aplikacji, po frontend (no ale to nie jest dziwne ;-)).<\/p>\n<p>Na pierwszy ogie\u0144 podczas mojej podr\u00f3\u017cy posz\u0142a mo\u017cliwo\u015b\u0107 napisania w JavaScript prostego serwera HTTP. Zadanie nie jest trudne.<\/p>\n<p>Zak\u0142adam, \u017ce zainstalowany jest ju\u017c interpreter Node.js, w kt\u00f3rym b\u0119d\u0105 uruchamiane nasze skrypty oraz mamy zainstalowany NPM do zarz\u0105dzania pakietami. No to do boju&#8230;<\/p>\n<p>W pierwszej kolejno\u015bci musimy pobra\u0107 pakiet <strong><u>http-server<\/u><\/strong> za pomoc\u0105 polecenia:<\/p>\n<pre><code>\r\nnpm install http-server --save\r\n<\/code><\/pre>\n<div style=\"border: 2px black solid; background-color: #4adfe8; padding: 5px 5px 5px 5px; font-family: Helvetica; font-size: 10pt\"><\/br><br \/>\nInstalujemy pakiet tylko w naszym projekcie, ale je\u015bli potrzebujecie mo\u017cna zainstalowa\u0107 go jako globalny wykorzystuj\u0105c prze\u0142\u0105cznik <strong><em>-g<\/em><\/strong>.\n<\/div>\n<p>Idziemy do kodu. Poni\u017cej przyk\u0142ad najprostszego serwera HTTP:<\/p>\n<pre><code>\r\nvar http = require('http');\r\nvar port = process.env.port || 8080;\r\nhttp.createServer(function ( request, response) {\r\n    res.writeHead(200, { 'Content-Type': 'text\/plain' });\r\n    res.end('Hello World\\n');\r\n}).listen(port);\r\n<\/code><\/pre>\n<p>Niezbyt ambitnie, co? W pierwszej kolejno\u015bci dodajemy instancj\u0119 pakietu serwera http i definiujemy port. Nast\u0119pnie poleceniem <code>createServer()<\/code> tworzymy instancj\u0119 serwera i przekazujemy do niej funkcj\u0119 obs\u0142uguj\u0105c\u0105 ka\u017cde \u017c\u0105danie (ang. handler). Funkcja ta przyjmuje dwa parametry reprezentuj\u0105ce \u017c\u0105danie i odpowied\u017a serwera. Czyli zgodnie z intuicj\u0105, czytamy co jest w \u017c\u0105daniu (ang. request), a wynik zapisujemy w odpowiedzi (ang. response).<\/p>\n<p>Nasz serwer jest do\u015b\u0107 ubogi, gdy\u017c aktualnie na ka\u017cde \u017c\u0105danie odpowie prostym &#8222;Hello World&#8221;. Spr\u00f3bujmy go troch\u0119 zr\u00f3\u017cnicowa\u0107. Napiszmy kawa\u0142ek kodu, kt\u00f3ry powita nas gdy w URL napiszemy (..)\/hello i po\u017cegna &#8211; gdy (..)\/bye . Aby to zrobi\u0107 musimy odpowiednio zmodyfikowa\u0107 funkcj\u0119 obs\u0142uguj\u0105c\u0105 \u017c\u0105danie.<\/p>\n<pre><code>\r\nvar http = require('http');\r\nvar port = process.env.port || 8080;\r\nhttp.createServer(function (req, res) {\r\n    var retval;\r\n    switch (req.url.substr(1).split(\"\/\")[0]) {\r\n        case \"hello\":\r\n            retval = \"Hello world\";\r\n            break;\r\n        case \"bye\":\r\n            retval = \"Bye world\";\r\n            break;\r\n        default:\r\n            res.writeHead(404, \"Unknown resource\")\r\n            res.end();\r\n            break;\r\n    }\r\n    \r\n    res.writeHead(200, { 'Content-Type': 'text\/plain' });\r\n    res.end(retval + '\\n');\r\n}).listen(port);\r\n<\/code><\/pre>\n<p>Parametr <code>request<\/code> posiada w\u0142a\u015bciwo\u015b\u0107 <Code>url<\/code>, kt\u00f3ry zawiera przekazan\u0105 tre\u015b\u0107 adresu. Wystarczy odpowiedni\u0105 instrukcj\u0105 sprawdzi\u0107 jej warto\u015b\u0107 i zareagowa\u0107. Zauwa\u017ccie, \u017ce nasz serwer na ka\u017cde inne \u017c\u0105danie ni\u017c opisane wy\u017cej odpowie kodem HTTP 404.<\/p>\n<p>Nasze rozwi\u0105zanie nie jest idealne, ale wystarczaj\u0105ce do prostych rozwi\u0105za\u0144. Gdy \u015bcie\u017cek, kt\u00f3re b\u0119dziemy chcieli obs\u0142ugiwa\u0107 b\u0119dzie bardzo du\u017co, musimy w jaki\u015b spos\u00f3b zarz\u0105dza\u0107 funkcjami je obs\u0142uguj\u0105cymi i wygodnie te \u015bcie\u017cki obs\u0142ugiwa\u0107. Do tego celu mo\u017cemy wykorzysta\u0107 jeden z wielu pakiet\u00f3w obs\u0142uguj\u0105cych routingi (np. http-router, router, routes-router, &#8230;). Ale o tym ju\u017c w nast\u0119pnym wpisie&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zapewne jak wi\u0119kszo\u015b\u0107 z deweloper\u00f3w backend&#8217;owych j\u0119zyk JavaScript kojarzy mi si\u0119 z tworzeniem raczej frontendu&#8217;u. Nie lubimy go, bo&#8230; jest inny. Pisz\u0105c skrypty dla UI cz\u0119sto spotyka\u0142em si\u0119 z sytuacj\u0105, \u017ce co\u015b nie dzia\u0142a i nie wiedzia\u0142em dlaczego. Sprawy nie u\u0142atwia\u0142 brak wsparcia dla debugowania, przynajmniej do czasu, a\u017c zacz\u0105\u0142em wykorzystywa\u0107 odpowiednie dodatki do przegl\u0105darek.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-60","post","type-post","status-publish","format-standard","hentry","category-dajsiepoznac"],"_links":{"self":[{"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/posts\/60","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/comments?post=60"}],"version-history":[{"count":18,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions"}],"predecessor-version":[{"id":110,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions\/110"}],"wp:attachment":[{"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/media?parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/categories?post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brozanski.net\/index.php\/wp-json\/wp\/v2\/tags?post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}