Node.js、Express、およびMongoDB:30分でAPI

初心者プログラマーにとって、Node.jsの開発は悪夢のように思えるかもしれません。 この理由は、このプラットフォームの柔軟性と明確なガイドラインの欠如です。 しかし、実際には、すべてがそれほど怖いわけではありません。









たとえば、典型的なタスク:REST APIの開発、特定のアプリケーションのバックエンド。 Nodeの豊富な機能と、この問題を解決するのに役立つ多くの追加モジュールは、豊富な選択肢に起因する行き詰まりに初心者を導く可能性があります。 ここでの主な問題は、コンポーネントの選択とそれらのコラボレーションの構成です。



アプリケーションのサーバー側を作成する方法の1つは、Node.js、Expressフレームワーク、およびMongoDB DBMSのバンドルを使用することです。 実際、今日は、ほぼすべてのアプリケーションの基盤として機能する、実用的なAPIレイアウトを作成する方法について説明します。 ここでは、メインのRESTルートを実装し、HTTPを介してAPIと対話し、データベースを操作するための簡単なオプションを使用します。



この資料を適切にマスターするには、REST APIとは何かを理解し、CRUD操作を理解し、JavaScriptの基本的な知識が必要です。 ここでは、特に複雑なものではなく、主に矢印関数であるES6を使用します。



Google Keepと同様に、メモを作成するためのアプリケーションのサーバー側のスケルトンを開発します。 同時に、ノートを使用して4つのCRUDアクションすべて(つまり、作成、作成、読み取り、更新、削除)を実行できます。



事前準備



Nodeがまだない場合は、 インストールします。 インストール後、フォルダーを作成し、コマンドを実行してその中の新しいプロジェクトを初期化します。



npm init
      
      





初期化中に、質問に答えてください。特に、アプリケーションに「注目すべき」(または、必要に応じて他の名前)の名前を付けます。



これで、 package.jsonファイルがフォルダーに表示されます。 これは、プロジェクトが依存する追加パッケージのインストールを開始できることを意味します。



フレームワークとして、Expressを使用する予定です。 データベース管理システムはMongoDBになります。 さらに、JSONでの作業を支援するために、body-parserパッケージを使用します。 これをすべてインストールします。



 npm install --save express mongodb body-parser
      
      





また、Nodemonをdev依存関係としてインストールすることを強くお勧めします。 これは、ファイルを変更すると自動的にサーバーを再起動するシンプルな小さなパッケージです。



このパッケージをインストールするには、次のコマンドを実行します。



 npm install --save-dev nodemon
      
      





その後、次のスクリプトをpackage.jsonファイルに追加できます。



 // package.json "scripts": {   "dev": "nodemon server.js" },
      
      





完成したpackage.jsonは次のようになります。



 // package.json { "name": "notable", "version": "1.0.0", "description": "", "main": "server.js", "scripts": {   "dev": "nodemon server.js" }, "author": "", "license": "ISC", "dependencies": {   "body-parser": "^1.15.2",   "express": "^4.14.0",   "mongodb": "^2.2.16" }, "devDependencies": {   "nodemon": "^1.11.0" } }
      
      





ここで、 server.jsファイルを作成し、APIの使用を開始します。



サーバー



server.jsファイル内の依存関係を接続することから始めましょう。



 // server.js const express        = require('express'); const MongoClient    = require('mongodb').MongoClient; const bodyParser     = require('body-parser'); const app            = express();
      
      





MongoClientを使用してデータベースと対話します。 また、ここでは、Expressフレームワークのインスタンスを使用して、アプリケーションを象徴するapp



定数を初期化します。 サーバーを機能させるために残っているのは、アプリケーションにHTTP要求のリッスンを開始するように指示することだけです。



ここでポートを指定し、次のようにリスニングを開始します。



 // server.js const port = 8000; app.listen(port, () => { console.log('We are live on ' + port); });
      
      





npm run dev



コマンド(またはNodemonをインストールしなかった場合はnode server.js



)を実行すると、「We are live on port 8000」というメッセージがターミナルに表示されます。



したがって、サーバーは動作しています。 しかし今、彼は何の役にも立ちません。 それを理解しましょう。



CRUD操作指向のルート



4つのルートを作成する予定です。 すなわち:





このスキームを習得すると、Nodeを使用して、ほとんどすべての必要なRESTルートを編成する方法を理解できます。



APIをテストするには、アプリケーションのクライアント側からのリクエストをシミュレートできるものが必要です。 Postmanと呼ばれる優れたプログラムがこの問題の解決に役立ちます。 これにより、特定のボディとパラメーターを使用して単純なHTTP要求を実行できます。



Postmanをインストールします。 これで、ルートをセットアップする準備ができました。



プロジェクト構造について



ほとんどのNode.jsマニュアル(および多くの実際のアプリケーション)では、すべてのルートは1つの大きなroute.jsファイルに配置されます。 私はこのアプローチがあまり好きではありません。 ファイルを異なるフォルダーに配置すると、コードの可読性が向上し、アプリケーションの管理が容易になります。



私たちのアプリケーションは大きなものとは言えませんが、その控えめな規模を考慮して、必要なすべてを行うことを提案します。 次のフォルダーを作成します: アプリフォルダー、およびその中のルートroutesフォルダーで、 index.jsおよびnote_routes.jsファイルを作成します 。 言い換えると、プロジェクト構造は次のようになります: root> app> routes> index.js and note_routes.js



 mkdir app cd app mkdir routes cd routes touch index.js touch note_routes.js
      
      





このような構造は、小さなアプリケーションでは冗長に見えるかもしれませんが、この例に基づいた大規模なシステムでは非常に役立つことがわかります。 さらに、既存の開発を最大限に活用してプロジェクトを開始することをお勧めします。



メモの作成:ルートの作成



CREATEルートから始めましょう。 これを行うには、「メモの作成方法」という質問に答えます。

メモの作成を開始する前に、アプリケーションインフラストラクチャを拡張する必要があります。 Expressでは、ルートはExpressのインスタンスとデータベースを引数として取る関数にラップされます。



次のようになります。



 // routes/note_routes.js module.exports = function(app, db) { };
      
      





これで、 index.jsを使用してこの関数をエクスポートできます。



 // routes/index.js const noteRoutes = require('./note_routes'); module.exports = function(app, db) { noteRoutes(app, db); // , ,      };
      
      





何が起こったかをserver.jsにインポートします



 // server.js const express        = require('express'); const MongoClient    = require('mongodb').MongoClient; const bodyParser     = require('body-parser'); const app            = express(); const port = 8000; require('./app/routes')(app, {}); app.listen(port, () => { console.log('We are live on ' + port); });
      
      





データベースをまだ構成していないため、空のオブジェクトが2番目の引数として渡されることに注意してください。



次に、CREATEルートを作成します。 ここの構文は非常に単純です:



 module.exports = function(app, db) { app.post('/notes', (req, res) => {   //    .   res.send('Hello') }); };
      
      





アプリケーションが '/ notes'パスに沿ってPOSTリクエストを受信すると、コールバック関数内でコードを実行し、リクエストオブジェクト(リクエストパラメーターまたはJSONデータを含む)とレスポンスオブジェクト(もちろん応答に使用されます)を渡します。



私たちが行ったことはすでにテストできます。 Postmanを使用して、 localhost:8000 / notesに POSTリクエストを送信します





リクエストに応えて「Hello」が来るはずです



素晴らしい。 最初のルートが作成されます。 次のステップでは、リクエストにパラメーターを追加し、APIで処理し、最後にデータベースにメモを保存します。



リクエストパラメータ



Postmanで[ ボディ ]タブに移動し、 x-www-form-urlencodedラジオボタンを選択して、キーと値のペアをいくつか追加します。 つまり、最初のキーはtitleで 、その値はMy Note Titleです。 2番目のキーはボディであり 、その値はなんとすばらしいメモです。



これにより、APIで処理できるエンコードされたデータがリクエストに追加されます。





私の記事のタイトルは、それ自体が非常にシンプルで、ここに想像力を示すことができます



note_route.jsファイルでは、コンソールにノートの本文を出力するだけです。



 // note_routes.js module.exports = function(app, db) { app.post('/notes', (req, res) => {   console.log(req.body)   res.send('Hello') }); };
      
      





Postmanを使用してリクエストを送信すると、... undefined



と表示されます。



残念ながら、ExpressはURLエンコードされたフォームを単独で処理できません。 ここでは、以前にインストールされたbody-parserパッケージが役立ちます。



 // server.js const express        = require('express'); const MongoClient    = require('mongodb').MongoClient; const bodyParser     = require('body-parser'); const app            = express(); const port = 8000; app.use(bodyParser.urlencoded({ extended: true })); require('./app/routes')(app, {}); app.listen(port, () => { console.log('We are live on ' + port); });
      
      





これで、POSTリクエストを実行した後、その本文は端末でオブジェクトとして見ることができます。



 { title: 'My Note Title', body: 'What a great note.' }
      
      





最初のルートが完全に機能するためには、データベースを構成してメモを追加するだけです。



データベースをすばやく作成して構成するには、 mLabサービスを使用します。 簡単に使用でき、少量の情報については無料です。



mLabでアカウントを作成し、新しいMongoDBデータベースを展開します。 これを行うには、 MongoDB DeploymentsセクションのCreate Newボタンをクリックし、表示されるウィンドウのPlanセクションで、 Single-nodeを選択します 。 [ 標準行]リストで、[ サンドボックス]を選択し、データベースに名前を付けます。 次に、データベース管理ウィンドウで、[ ユーザー ]タブに移動し、名前とパスワードを指定してデータベースユーザーを追加します。





新しいデータベースユーザー



同じページ(データベース接続文字列)から2番目のURLをコピーします。





データベースに接続するためのURL



configディレクトリをプロジェクトルートに追加し、その中にdb.jsファイルを作成します。



 mkdir config cd config touch db.js
      
      





以下をdb.jsファイルに追加します。



 module.exports = { url :    URL };
      
      





ユーザー名とパスワードをURLに追加することを忘れないでください(mLabアカウントのものではなく、データベース用に作成されたもの)。 Githubでプロジェクトをホストする場合は、 .gitignoreファイル( このような)を必ず含めてください 。 そのため、データベースを操作するためのパブリックドメイン名とパスワードは作成しません。



server.jsでは、MongoClientを使用してデータベースに接続し、アプリケーション設定を作成するときにデータベースに渡される関数をラップできます。



 // server.js const express        = require('express'); const MongoClient    = require('mongodb').MongoClient; const bodyParser     = require('body-parser'); const db             = require('./config/db'); const app            = express(); const port = 8000; app.use(bodyParser.urlencoded({ extended: true })); MongoClient.connect(db.url, (err, database) => { if (err) return console.log(err) require('./app/routes')(app, database); app.listen(port, () => {   console.log('We are live on ' + port); });              })
      
      





これで、インフラストラクチャの準備が完了しました。 これからは、パスのみを扱います。



データベースへのレコードの追加



MongoDBは、名前を完全に正当化するコレクションにデータを保存します。 この場合、ノートはコレクションに保存されます。コレクションは、ご想像のとおり、 notes



と呼ばれnotes







クライアントのセットアップ中に、データベース接続文字列が渡されました、 db



引数。 経路コードでは、データベースへのアクセスは次のように取得できます。



 db.collection('notes')
      
      





データベースにメモを作成することは、 notes



コレクションに対してinsert



コマンドを呼び出すことと同じです。



 const note = { text: req.body.body, title: req.body.title} db.collection('notes').insert(note, (err, results) => { }
      
      





コマンドが正常に完了した後(または何らかの理由で実行できない場合)、新しく作成されたノートオブジェクトを応答で送信するか、エラーメッセージを送信する必要があります。 以下は、これらの考慮事項を考慮して補足されたnote_routes.jsコードです。



 // note_routes.js module.exports = function(app, db) { app.post('/notes', (req, res) => {   const note = { text: req.body.body, title: req.body.title };   db.collection('notes').insert(note, (err, result) => {     if (err) {       res.send({ 'error': 'An error has occurred' });     } else {       res.send(result.ops[0]);     }   }); }); };
      
      





何が起こったかを体験してください。 Postmanから( x-www-form-urlencodedフラグを使用して)POST要求を送信し、[ 本文 ]タブのタイトル本文フィールドの値を設定します。



答えは次のようになります。





データベースへのレコードの追加に成功しました



mLabにログインしてデータベースを見ると、新しく作成されたメモを見つけることができます。



メモを読む:ルートを読む



上記で準備したインフラストラクチャはすべてのルートに適しているため、現在はより高速になります。



そのため、 localhostパス8000 / notes / {note id}に従って、作成したばかりのメモを要求します。 この場合、パスはlocalhost:8000 / notes / 585182bd42ac5b07a9755ea3のようになります。



作成済みのメモのIDがない場合は、mLabでデータベースを検索してそこを見つけるか、新しいメモを作成してその識別子をコピーします。



note_route.jsでの表示は次のとおりです。



 // note_routes.js module.exports = function(app, db) { app.get('/notes/:id', (req, res) => {   }); app.post('/notes', (req, res) => {   const note = { text: req.body.body, title: req.body.title };   db.collection('notes').insert(note, (err, result) => {     if (err) {       res.send({ 'error': 'An error has occurred' });     } else {       res.send(result.ops[0]);     }   }); }); };
      
      





前と同じように、ノートデータベースを収集するコマンドを呼び出します。 このためにfindOne



メソッドを適用します。



 // note_routes.js module.exports = function(app, db) { app.get('/notes/:id', (req, res) => {   const details = { '_id': <  ID> };   db.collection('notes').findOne(details, (err, item) => {     if (err) {       res.send({'error':'An error has occurred'});     } else {       res.send(item);     }   }); }); app.post('/notes', (req, res) => {   const note = { text: req.body.body, title: req.body.title };   db.collection('notes').insert(note, (err, result) => {     if (err) {       res.send({ 'error': 'An error has occurred' });     } else {       res.send(result.ops[0]);     }   }); }); };
      
      





URLパラメーターからの識別子は、 req.params.id



コンストラクトを使用してreq.params.id



ことができます。 ただし、上記のコードから<< >>の代わりに単純に行を挿入する場合、これは機能しません。



MongoDBには、文字列としてではなく、特別なオブジェクトとしてのIDが必要です。 これはObjectIDと呼ばれます



少し変更した後、次のようにしました。



 // note_routes.js var ObjectID = require('mongodb').ObjectID; module.exports = function(app, db) { app.get('/notes/:id', (req, res) => {   const id = req.params.id;   const details = { '_id': new ObjectID(id) };   db.collection('notes').findOne(details, (err, item) => {     if (err) {       res.send({'error':'An error has occurred'});     } else {       res.send(item);     }   }); }); app.post('/notes', (req, res) => {   const note = { text: req.body.body, title: req.body.title };   db.collection('notes').insert(note, (err, result) => {     if (err) {       res.send({ 'error': 'An error has occurred' });     } else {       res.send(result.ops[0]);     }   }); }); };
      
      





データベースで利用可能なノート識別子のいずれかで試してください。 Postmanの答えは次のようになります。





データベースからのメモの正常なリクエスト



メモを削除:ルートを削除



オブジェクトの削除は、データベースでの検索とほぼ同じです。 findOne



関数の代わりにのみ、 remove



関数が使用されます。 以下は、対応するパスの完全なコードです。 ここで強調されるのは、GETリクエストを処理する既存のメソッドのコードとは異なるということです。



 // note_routes.js // ... app.delete('/notes/:id', (req, res) => {   const id = req.params.id;   const details = { '_id': new ObjectID(id) };   db.collection('notes').remove(details, (err, item) => {     if (err) {       res.send({'error':'An error has occurred'});     } else {       res.send('Note ' + id + ' deleted!');     }   }); }); // ...
      
      





更新ノート:ルートの更新



そして、これが最後のルートです。 PUT要求処理は、基本的にREAD操作とCREATE操作のハイブリッドです。 最初にオブジェクトを見つける必要があり、次にリクエストで受信したデータに従ってオブジェクトを更新します。 ここで、以前のコードフラグメントを経験した場合、唯一のノートを削除して、別のノートを作成します。



メモ更新ルートコードは次のとおりです。



 // note_routes.js // ... app.put ('/notes/:id', (req, res) => {   const id = req.params.id;   const details = { '_id': new ObjectID(id) };   const note = { text: req.body.body, title: req.body.title };   db.collection('notes').update(details, note, (err, result) => {     if (err) {         res.send({'error':'An error has occurred'});     } else {         res.send(note);     }   }); }); // ...
      
      





これで、任意のメモを編集できます。 これは次のようなものです。





メモを更新しました



この例の欠陥に注意してください。 PUTリクエストに本文またはタイトルがない場合、データベース内の対応するフィールドは単純にクリアされます。



追加のチェックを含む例をロードしませんでした。 必要に応じて、要求が正しく形成された場合にのみ、データベースに新しいデータを追加することにより、ノートの更新操作を完了できます。



まとめ



これで、4つの基本的なCRUD操作をサポートする有効なNode APIができました。 アプリケーションのサーバー部分は、クライアントのHTTPリクエストに応じて、データベースにメモを作成し、それらを見つけ、削除し、編集することができます。



私の話の主な目標は、Node + Express + MongoDBの束とサーバーアプリケーション開発の方法論を全員に知らせることです。 もちろん、今日これらのツールを初めて知った場合は、すべてをよりよく理解するために、ドキュメントを読む必要があります。 ただし、何が起こっているのかを理解することで、ここで作業したアプリケーションを出発点として、知識のギャップをすぐに埋め、独自のプロジェクトで作業を開始できます。



実際のプロジェクトでNode.js、Express、およびMongoDBの使用経験がある場合は、初心者に役立つものをお勧めしますか? そして、これらすべてを初めて試したばかりの場合-あなたの印象を待っています。



All Articles