Створення RESTful сервісів на Meteor

Введення: Навіщо потрібен RESTful сервіс на Meteor

Meteor приваблює простотою використання і можливістю дуже швидко створити працює додаток з мінімальним набором функцій. У Meteor — добре розвинена спільнота. Є безліч корисних додаткових модулів, які не вимагають складної настройки, і можуть бути використані відразу після установки. Є хороша документація, приклади і велику кількість постів на форумах, на зразок StackOverflow. Meteor — це full-stack фреймворк, який пропонує зручну й багатофункціональну інтеграцію сервера з клієнтом. Так навіщо ж виходити за рамки цієї взаємодії, і створювати RESTful сервіс?

Клієнт-серверний додаток, по-суті, складається з 2 незалежних частин, які взаємодіють за допомогою певного інтерфейсу. При цьому кожна з частин клієнт-серверного додатка може створюватися різними людьми або командами. Розробники клиенсткой частини зовсім не обмежені використанням Meteor, вони можуть використовувати будь-який інший JS фреймворк, клієнт навіть не обов'язково повинен бути написаний на PHP, це може бути наприклад додаток Android, написаний на Java, або iOS, написане на Objective C.

Саме ці причини змусили мене вибрати Meteor для побудови back end в моєму проекті, і шукати шляхи для створення RESTful сервісу на Meteor.

Огляд наявних модулів

Після деякого часу, витраченого на пошук підходящий модулів, у мене з'явився наступний список:

github.com/meteorhacks/picker — використовує маршрутизацію аналогічну тій, що використовується, скажімо, Express.js

Picker.route('/post/:_id', function(params, req, res, next) {
var post = Posts.findOne(params._id);
res.end(post.content);
});

з можливістю відправлення відповіді у форматі JSON

github.com/crazytoad/meteor-collectionapi дозволяє створити API Endpoints для CRUD операцій над колекціями. Немає механізмів для розмежування рівнів доступу (наприклад: гість, авторизований користувач, адміністратор), авторизації або створення custom endpoints.

github.com/kahmali/meteor-restivus дозволяє створити API Endpoints для CRUD операцій над колекціями. Є механізми авторизації, розмежування рівнів доступу та створення custom endpoints. Про це пакеті буде розказано детальніше трохи нижче.

github.com/Differential/reststop2 — устаравшее і непідтримувану рішення. На головній сторінці ресурсу, посилання на проект Restivus із зазначенням про те, що всі наявні функції цього рішення також є і в Restivus.

github.com/stubailo/meteor-rest дозволяє створити API Endpoints для CRUD операцій над колекціями. Є механізми авторизації і створення custom endpoints. Немає механізмів для розмежування рівнів доступу. Документації не вистачає ясності і працюють прикладів. Дозволяє інтегрувати Restivus для створення custom endpoints.

Оскільки Restivus має весь необхідний мені набір функцій, і був відзначений найбільшим кількістю зірок як на GitHub, так і на Atmosphere, а також з причини того, що 2 інших проекту з наведеного списку посилалися на Restivus, я вирішив зупинити свій вибір саме на ньому.

Використання колекцій, CRUD операції і рівні доступу

Використовувати Restivus — дуже просто. Щоб встановити, введіть в консолі:

meteor add nimble:restivus

Щоб створити RESTful сервіс, додайте в серверний код такі строки:

if (Meteor.isServer) {
var Api = new Restivus({useDefaultAuth: true});
}

В аргументах конструктора передаються опції API. Значення опції `useDefaultAuth` розглянемо в слеудющем розділі.

Якщо у вас зареєстрована колекція, скажімо

var Contacts = new Mongo.Collection('contacts');

І ви хочете відкрити до неї доступ допомогою CRUD операцій через API, у найпростішій формі, досить зробити:

Api.addCollection(Contacts);

Це створить такі Endpoints:

`getAll` Endpoint
GET /api/collection
Повернути інформацію про всі елементи колекції

`post` Endpoint
POST /api/collection
Додати новий елемент в колекцію

`get` Endpoint
GET /api/collection/:id
Повернути інформацію про елемент колекції

`put` Endpoint
PUT /api/collection/:id
Редагувати елемент колекції

`delete` Endpoint
DELETE /api/collection/:id
Видалити елемент колекції

Формат відповіді завжди наступний:

{status: "success", data: {}}

Префікс `api/` може бути замінений на інший за допомогою установки опції `apiPath`, переданої при створенні API. Як ви бачите, у кожній API операції над колекцією є свій ідентифікатор. Він може бути використаний наступним чином:

Api.addCollection(Contacts, {
excludedEndpoints: ['getAll', 'put'],
routeOptions: {
authRequired: true
},
endpoints: {
get: {
authRequired: false
},
delete: {
roleRequired: 'admin'
}
}
});

У цьому випадку в API була зареєстрована колекція з операціями delete, get і post. Для операції get авторизація не потрібна, для операцій post і delete — потрібно, при цьому для операцію delete може виконати тільки адміністратор. Про авторизації і аутентифікації читайте далі

Ідентифікація і аутентифікація

Після реєстрації в API колекції users додаються 2 спеціальні endpoints:

POST /api/login
GET|POST /api/logout

Незважаючи на запевнення з документації, у версії Restivus, яку використовував я (0.8.4), разлогивание працювало тільки при GET запиті. Більш докладно про це можете подивитися тут.

Щоб авторизуватися, потрібно передати ім'я користувача і пароль в наступному вигляді:

curl http://localhost:3000/api/login/ -d "username=test&password=password"

У разі невдачі в тілі відповіді прийде рядок 'Unauthorized'.
У разі успіху прийде наступний відповідь:

{status: "success", data: {authToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ}}

Збережіть токен і id користувача, щоб передавати в заголовках запитів до API Endpoints, що вимагають авторизації:

curl -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ" http://localhost:3000/api/contacts/


Custom Endpoints

Api.addRoute('contacts/favorite/:userId', {
get: {
authRequired: false,
roleRequired: ['author', 'admin'],
action: function () {
this.response.write({"user-id": this.urlParams.userId});
this.done();
}
}
});

Цей фрагмент коду реєструє API Endpoint за адресою api/contacts/favorite/. Параметр `userId`, переданий як частину шляху, буде доступний як `this.urlParams.userId`. Параметри GET запиту будуть доступні через `queryParams`. Якщо не потрібно описувати опції для авторизації рівнів доступу, то можна використовувати коротку форму:

Api.addRoute('contacts/favorite/:userId', {
get: function () {
this.response.write({"user-id": this.urlParams.userId});
this.done();
}
});

Підсумки: За і проти побудови RESTful сервісу на Meteor

Як ми бачимо, Meteor в черговий раз надав зручний інструмент для швидкого створення прототипу, що є дуже цінним на ранніх стадіях проекту. Нерідко програми не виходять за рамки роботи з тектовыми і числовими даними. Таким чином ми маємо: Meter і Restivus + resource механізм (наявний, наприклад в Angular або Vue) = взаємодія між клієнтом і сервером, створене за лічені хвилини.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.