أنشئ واجهة برمجة تطبيقات Node.js في أقل من 30 دقيقة

أنشئ واجهة برمجة تطبيقات Node.js في أقل من 30 دقيقة

يمكن أن يكون Node.js مخيفًا للمبتدئين. لكن هيكلها المرن وافتقارها إلى إرشادات صارمة يجعلها تبدو أكثر تعقيدًا مما هي عليه.

هذا البرنامج التعليمي هو دليل سريع وبسيط لـ Node.js ، وإطار العمل السريع ، و MongoDB ، مع التركيز على مسارات REST الأساسية وتفاعل قاعدة البيانات الأساسية. ستقوم بإنشاء نموذج معياري بسيط لواجهة برمجة التطبيقات يمكن استخدامه بعد ذلك كأساس لأي تطبيق.

لمن هذا البرنامج التعليمي : يجب أن يكون لديك فهم أساسي لواجهات برمجة تطبيقات REST وعمليات CRUD ، بالإضافة إلى معرفة JavaScript الأساسية. أستخدم ES6 (وظائف سهم الدهون بشكل أساسي) ، لكن لا شيء معقد للغاية.

في هذا البرنامج التعليمي ، ستنشئ الهيكل العظمي للخلفية لتطبيق تدوين الملاحظات - فكر في Google Keep. تريد أن تكون قادرًا على القيام بجميع إجراءات CRUD الأربعة على ملاحظاتك: إنشاء وقراءة وتحديث وحذف.

اعداد

إذا لم يكن لديك Node مثبتًا ، انظر هنا.

في دليل جديد ، قم بتشغيل npm init ، واتبع التعليمات ، مع إعطاء تطبيقك اسم "ملحوظ" (أو أي شيء آخر قد يعجبك).

npm init

بمجرد الانتهاء من ذلك ، يجب أن يكون لديك package.json جاهزًا للذهاب إلى دليلك . هذا يعني أنه يمكنك البدء في تثبيت التبعيات التي تحتاجها لمشروعك.

ستستخدم Express كإطار عمل خاص بك ، و MongoDB كقاعدة بيانات ، وحزمة تسمى body-parser للمساعدة في التعامل مع طلبات JSON.

npm install --save express [email protected] body-parser

أوصي بشدة أيضًا بتثبيت Nodemon كاعتماد على dev. إنها حزمة صغيرة بسيطة تعيد تشغيل الخادم تلقائيًا عندما تتغير الملفات.

اذا ركضت:

npm install --save-dev nodemon

يمكنك بعد ذلك إضافة البرنامج النصي التالي إلى package.json :

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

يجب أن تبدو حزمة 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 ، إطار العمل الخاص بك.

آخر شيء عليك القيام به لتنشيط خادمك وتشغيله هو إخبار تطبيقك ببدء الاستماع لطلبات HTTP.

يمكنك تحديد منفذ والبدء في الاستماع كما يلي:

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

الآن إذا قمت بتشغيل npm run dev (أو node server.js إذا لم تقم بتثبيت Nodemon) ، فسترى "نحن نعيش على المنفذ 8000" في المحطة.

خادمك مباشر. لكنها لا تفعل الكثير. أو أي شيء ، حقًا.

دعونا نصلح ذلك.

الطرق الوعرة

في هذا المثال ، تريد بناء 4 مسارات ؛ لإنشاء ملاحظة ، لقراءة ملاحظاتك ، لتحديث ملاحظة ، ولحذف ملاحظة.

سيعطيك هذا فكرة جيدة عن كيفية هيكلة أي مسار أساسي تقريبًا باستخدام Node.

لاختبار API الخاص بك ، على الرغم من ذلك ، تحتاج إلى تقليد جانب العميل الذي يقوم بتقديم الطلبات. للقيام بذلك ، ستستخدم تطبيقًا رائعًا يسمى Postman. يسمح لك بإجراء طلبات HTTP بسيطة بهيئات ومعلمات مخصصة.

ثبّت Postman ، ودعنا نبدأ في إعداد مساراتك.

منظم سوبر

معظم نود.جي إس الدروس (والعديد من التطبيقات الحقيقية) وضعت جميع الطرق في واحدة كبيرة routes.js الملف. هذا يجعلني غير مرتاح قليلا. في المقابل ، يؤدي تقسيم ملفاتك إلى مجلدات منفصلة إلى إمكانية قراءة جيدة ، ويجعل التطبيقات الكبيرة أكثر قابلية للإدارة.

ليس لديك تطبيق كبير ، ولكن لنفعل ذلك بالشكل الصحيح. جعل الدلائل التالية: في التطبيق مجلد مع طرق مجلد داخله، مع index.js و note_routes.js ملف داخله.

بمعنى آخر: root> app> route> index.js و note_routes.js.

mkdir appcd appmkdir routescd routestouch index.jstouch note_routes.js

قد تبدو هذه الأدلة مبالغة في استخدام تطبيقك الصغير البسيط ، ولكن من الجيد دائمًا البدء بأفضل الممارسات.

طريقك الأول

لنبدأ بـ C في CRUD- إنشاء. كيف يمكنك إنشاء ملاحظة؟

Well, before you do that, you have to build a bit more infrastructure. In Express, routes are wrapped in a function, which takes the Express instance and a database as arguments.

Like this:

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

You can then export this function through your index.js:

// routes/index.js
const noteRoutes = require('./note_routes');
module.exports = function(app, db) { noteRoutes(app, db); // Other route groups could go here, in the future};

Then import it for use in 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);});

Note that since you don’t have a database yet set up, you’re just passing in an empty object.

Okay, now you can make your CREATE route.

The syntax is simple:

// note_routes.js
module.exports = function(app, db) { app.post('/notes', (req, res) => { // You'll create your note here. res.send('Hello') });};

When the app receives a post request to the ‘/notes’ path, it will execute the code inside the callback- passing in a request object (which contains the parameters or JSON of the request) and a response object (used to reply).

You can test this by using Postman to send a POST request to localhost:8000/notes.

Nice! You created your first real route.

Next step is to add some parameters to your request and process them in your API and, finally, add in your database.

Request Parameters

In Postman, go to the Body tab and add some key-value pairs, after selecting the x-www-form-urlencoded radio button.

This will add encoded form data to your request, which you’ll be able to process with your API.

Now in your note_routes.js, let’s just log out the body.

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

Try sending the Postman request and you’ll see… undefined.

Unfortunately, Express can’t process URL encoded forms on its own. But you did install that body-parser package…

// server.
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);});

Now you should see the body as an object in the terminal.

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

Last step to your preliminary route: set up the database, and then add your data in.

The easiest way to set up a Mongo database is through mLab: it’s free for the smallest size, and quite fast to setup.

Once you create an account and a MongoDB deployment, add a user to the database with a username and password:

then grab the URL here (the second one):

And in a directory config in the root of your project, create a db.js file.

mkdir config cd configtouch db.js

Inside, add the URL:

module.exports = { url : YOUR URL HERE};

Don’t forget to add your username and password (the ones from the database user, not your mLab account) into the URL. (If you’re committing this project to Github, be sure to include a .gitignore file like so, so you don’t share your password with everyone.)

Now in your server.js, you can use the MongoClient to connect to your DB, and use this to wrap your app setup:

// 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); }); })

If you’re using the latest version of the MongoDB (3.0+), modify it like so:

// 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) // Make sure you add the database name and not the collection name const database = database.db("note-api") require('./app/routes')(app, database);
 app.listen(port, () => { console.log('We are live on ' + port); }); })

(Thanks to Alex Stroulger for the fix for 3.0)

That’s the last of your infrastructure setup! It’s all route-building from here.

Adding to your Database

MongoDB stores data in collections- which are exactly how they sound. In your case, you want to store your notes in a collection called — you guessed it — notes.

Since you pass in your database as the db argument in your routes, you can then access it like so:

db.collection('notes')

Creating a note is as simple as calling insert on your collection:

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

Once the insert is complete (or has failed for whatever reason), you want to either send back an error or send back the newly created note object. Here’s the full note_routes.js:

// note_routes.js
module.exports = function(app, db) { const collection = 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]); } }); });};

Try it out! Send an x-www-form-urlencoded POST request with Postman, with a title and body set under the Body tab.

The response should look like this:

If you log into mLab, you should also see the created note in the database.

Your READ Route

Now you can pick up the pace a bit.

Say you wanted to get back the note you just created, by navigating to localhost:8000/notes/{the id}. In this case, that would be localhost:8000/notes/585182bd42ac5b07a9755ea3.

(If you don’t have the ID for one of your notes, you can check on mLab or just create a new one).

Here’s what this would look like in note_routes.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]); } }); });};

Just like before, you’re going to call a method on your database collection of notes. Here, it’s the aptly named findOne.

// note_routes.js
module.exports = function(app, db) { app.get('/notes/:id', (req, res) => { const details = { '_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]); } }); });};

You can grab the id from the URL parameters via req.params.id. However, if you try to just plop in the string into the above, it won’t work.

MongoDB requires not just an ID as a string, but as an ID object or, as they call it, an ObjectID.

Don’t worry, it’s an easy fix. Here’s the full code:

// 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]); } }); });};

Try it out with one of your note ID’s, and it should look like this:

Your DELETE Route

Deleting an object is actually pretty much the same as finding an object. You just use the remove function instead of the findOne. Here’s the full code. I’ve highlighted what’s different from your 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!'); } }); });
// ...

Your UPDATE Route

Last one! The PUT is basically a hybrid between READ and CREATE. You find the object, then update it accordingly. If you deleted your only note, time to make another one!

The code:

// 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); } }); });
// ...

Now you can update any of your notes, like so:

Note the imperfection with this code- if you fail to supply a body or title, the PUT request will nullify those fields on the note in the database.

You could easily add some conditional logic to update the fields only if they’re present in the request- I left that out just to keep it simple.

API Complete

That’s it! You have a working Node API with each of the four major CRUD operations.

The goal of this tutorial was to give you a degree of familiarity with Express, Node, and MongoDB — you can use your simple app as a launching pad for more complex projects.

في المستقبل سأكتب دروسًا لإنشاء واجهات برمجة تطبيقات أكثر بساطة بلغات وأطر عمل مختلفة. اضغط على زر المتابعة إذا كنت مهتمًا!

إذا كان هذا البرنامج التعليمي مفيدًا لك ، فالرجاء ضرب القلب الأخضر أدناه - فهذا يعني الكثير. لا تتردد في ترك تعليق لي مع أي ملاحظات أو أسئلة.

شكرا للقراءة!