この投稿は、Node.jsを使用したサーバー側のWeb開発についての詳細と、Express、Koa.js、Hapi.jsの3つの異なる環境を使用した簡単なHTTPサーバーの記述の簡単な比較です。
注:経験豊富なNode.js開発者であれば、おそらくこれは初歩的でシンプルだと思うでしょう。 ¯\ _(ツ)_ /¯。
ネットワークのいくつかの基本
数年前にWeb業界で働き始めたとき、 CourdraのDavid Veteral教授によるコンピューターネットワークのコースに出会いました。 残念ながら、それはもはや利用できませんが、講義はピアソンのウェブサイトでまだ利用可能です。
フードの下で何が起こっているのかをわかりやすい方法で説明したので、このコースがとても気に入りました。コンピューターネットワークの教科書を手に入れることができれば、ネットワークの驚異に関する詳細をすべて読んでください。

ただし、ここでは、コンテキストについて簡単に説明します。 HTTP(Hypertext Transfer Protocol)は、コンピューターネットワークで使用される通信プロトコルです。 インターネットには、 SMTP(簡易メール転送プロトコル) 、 FTP(ファイル転送プロトコル) 、 POP3(郵便局プロトコル3)などの多くのものがあります。
これらのプロトコルにより、明確に定義されたメッセージ形式、ルール、構文、セマンティクスなどを提供するため、完全に異なるハードウェア/ソフトウェアを備えたデバイスが相互に通信できます。 これは、デバイスが特定のプロトコルをサポートしている間、他のデバイスと通信できることを意味します。 ネットで。

TCP / IP対OSIから:2つのモデルの違いは何ですか?
通常、オペレーティングシステムには、HTTPなどのネットワークプロトコルがサポートされています。これは、インターネットにアクセスするために追加のソフトウェアを明示的にインストールする必要がない理由を説明しています。 ほとんどのネットワークプロトコルは、2つのデバイス間のオープン接続をサポートしているため、デバイス間でデータを転送できます。
ネットワークが実行されるHTTPは異なります。 リクエスト/レスポンスモードの操作に基づいているため、コネクションレスプロトコルとして知られています。 Webブラウザーは画像、フォント、コンテンツなどの要求をサーバーに送信しますが、要求が完了すると、ブラウザーとサーバー間の接続は切断されます。

サーバーとクライアント
サーバーという用語は、ハードウェア(Webサイトに必要なすべてのファイルとソフトウェアをホストする物理コンピューター)とソフトウェア(プログラムの両方)の両方を指すことがあるため、業界に初めて参入する人々にとって少し混乱する可能性がありますユーザーがこれらのファイルにオンラインでアクセスできるようにします)。
今日は、ソフトウェアの側面についてお話します。 しかし、最初に、いくつかの定義。 URLはUniversal Resource Locatorを表し、 プロトコル 、 サーバー、および要求されたファイルの3つの部分で構成されます 。

URL構造
HTTPプロトコルは、ブラウザがさまざまなアクションの実行をサーバーに要求するために使用できるいくつかのメソッドを定義します。最も一般的なのはGETとPOSTです。 ユーザーがリンクをクリックするか、URLをアドレスバーに入力すると、ブラウザーはGET要求をサーバーに送信して、URLで指定されたリソースを取得します。
サーバーは、正しいファイルを取得するためにこのHTTP要求を処理する方法を知っている必要があり、それを要求したブラウザーに送り返します。 これを処理する最も人気のあるWebサーバーソフトウェアはApacheとNGINXです。

Webサーバーは着信要求を処理し、それに応じて応答します
どちらも、認証スキーム、URL書き換え、ログ記録、プロキシなどの機能を含むフル機能のオープンソースソフトウェアパッケージです。 ApacheとNGINXはCで記述されています。技術的には、任意の言語でWebサーバーを記述できます。 Python 、 golang.org/pkg/net/http 、 Ruby 、このリストはかなり長い間続く可能性があります。 一部の言語は特定のことを他の言語よりもうまく行うというだけです。
Node.jsを使用してHTTPサーバーを作成する
Node.jsは、 Chrome V8 Javascriptエンジン上に構築されたJavascriptランタイムです。 HTTPサーバーを構築するための一連の関数とクラスを提供するhttpモジュールが付属しています。
この基本的なHTTPサーバーでは、Node.jsネイティブモジュールであるファイルシステム 、 パス、およびURLも使用します 。
必要なモジュールをインポートすることから始めます。
const http = require('http') // HTTP- Node.js const fs = require('fs') // const path = require('path') // const url = require('url') // URL
また、MIMEタイプ辞書を作成して、その拡張子に基づいて、要求されたリソースに適切なMIMEタイプを割り当てることができます。 インターネット割り当て番号機関でMIMEタイプの完全なリストを見つけることができます。
const mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.ico': 'image/x-icon', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml', '.json': 'application/json', '.woff': 'font/woff', '.woff2': 'font/woff2' }
これで、
http.createServer()
関数を使用してHTTPサーバーを作成できます。これは、
http.Server
新しいインスタンスを
http.Server
ます。
const server = http.createServer()
リクエストハンドラ関数を、リクエストオブジェクトとレスポンスオブジェクトとともに
createServer()
渡します。 この関数は、HTTP要求がサーバーに到着するたびに1回呼び出されます。
server.on('request', (req, res) => { // })
サーバーを起動するには、サーバーにリッスンさせたいポート番号、たとえば
5000
を使用して
server
オブジェクトの
listen
メソッドを呼び出します。
server.listen(5000)
request
オブジェクトはIncomingMessageのインスタンスであり、レスポンスステータス、ヘッダー、データなど、リクエストに関するすべての情報にアクセスできます。
response
オブジェクトはServerResponseのインスタンスです。これは書き込み可能なストリームであり、クライアントにデータを送り返すための多くのメソッドを提供します。
クエリハンドラでは、次のことを行います。
- 着信リクエストを解析し、拡張なしで処理します
const parsedUrl = new URL(req.url, 'https://node-http.glitch.me/') let pathName = parsedUrl.pathname let ext = path.extname(pathName) // URL '/', '/' // URL 'Location' if (pathName !== '/' && pathName[pathName.length - 1] === '/') { res.writeHead(302, {'Location': pathName.slice(0, -1)}) res.end() return } // , index.html // «.html» if (pathName === '/') { ext = '.html' pathName = '/index.html' } else if (!ext) { ext = '.html' pathName += ext }
- いくつかの基本的なチェックを実行して、要求されたリソースが存在するかどうかを判断し、それに応じて応答します
// , const filePath = path.join(process.cwd(), '/public', pathName) // , fs.exists(filePath, function (exists, err) { // , 404 Not Found if (!exists || !mimeTypes[ext]) { console.log(' : ' + pathName) res.writeHead(404, {'Content-Type': 'text/plain'}) res.write('404 Not Found') res.end() return } // 200 OK, // res.writeHead(200, {'Content-Type': mimeTypes[ext]}) // const fileStream = fs.createReadStream(filePath) fileStream.pipe(res) })
すべてのコードはGlitchでホストされており、必要に応じてプロジェクトをリミックスできます。
https://glitch.com/edit/#!/node-http
Node.jsフレームワークでHTTPサーバーを作成する
Express 、 Koa.js 、 Hapi.jsなどのNode.jsフレームワークには、開発者が自分で記述しなくて済む便利な機能に加えて、さまざまな便利なミドルウェア機能が付属しています。
個人的には、最初にフレームワークなしで基本を学び、内部で何が起こっているのかを理解してから、好きなフレームワークに夢中になる方が良いと感じています。
Expressには静的ファイルを提供するための独自の組み込みプラグインがあるため、独自のNode.jsと同じアクションを実行するために必要なコードははるかに短くなります。
const express = require('express') const app = express() // app.use(express.static('public')) // index.html, // res.sendFile() app.get('/', (req, res) => { res.sendFile(__dirname + '/public/index.html') }) app.listen(5000)
Koa.jsにはコア内に同様のプラグインがないため、必要なプラグインは個別にインストールする必要があります。 Koa.jsの最新バージョンでは、コールバックを優先して非同期関数を使用しています。
koa-static
プラグインを使用して、静的ファイルを提供できます。
const serve = require('koa-static') const koa = require('koa') const app = new koa() // // koa-static index.html app.use(serve(__dirname + '/public')) app.listen(5000)
Hapi.jsはカスタマイズをサポートし、
server
オブジェクトのカスタマイズを中心に展開します。 プラグインを使用して、ルーティング、認証などの機能を拡張します。 静的ファイルを提供するには、
inert
というプラグインが必要です。
const path = require('path') const hapi = require('hapi') const inert = require('inert') // const server = new hapi.Server({ port: 5000, routes: { files: { relativeTo: path.join(__dirname, 'public') } } }) const init = async () => { // server.register() await server.register(inert) // inert // server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: '.', redirectToSlash: true, index: true } } }) await server.start() } init()
これらのプラットフォームにはそれぞれ長所と短所があり、単一のHTMLページを提供するだけでなく、大規模なアプリケーションの方が明らかになります。 構造の選択は、作業中のプロジェクトの実際の要件に大きく依存します。
完了
ネットワーク側が常にあなたにとってブラックボックスであった場合、この記事がネットワークを提供するプロトコルの有用な入門書として役立つことを願っています。 また、 Node.js APIドキュメントを読むことを強くお勧めします 。これは、非常によく書かれており、一般的なNode.jsの初心者にとって非常に便利です。